package com.cci.kangdao.service.impl;

import com.cci.kangdao.aop.UserThreadLocal;
import com.cci.kangdao.cipapi.CipApiUtils;
import com.cci.kangdao.cipapi.CipResponeEntity;
import com.cci.kangdao.cipapi.EsnBasicInfoEntity;
import com.cci.kangdao.common.RedisKeys;
import com.cci.kangdao.common.type.OverTimeType;
import com.cci.kangdao.crmapi.CRMApiUtils;
import com.cci.kangdao.crmapi.CRMResponeEntity;
import com.cci.kangdao.crmapi.CRMServiceApiImpl;
import com.cci.kangdao.crmapi.CRMServiceConst;
import com.cci.kangdao.dao.*;
import com.cci.kangdao.dao.model.*;
import com.cci.kangdao.dto.BaseResponse;
import com.cci.kangdao.dto.request.SaveRepairAckRequest;
import com.cci.kangdao.dto.response.WorkOrderReasonTimeoutRecordTVo;
import com.cci.kangdao.entity.WorkOrderCloseEntity;
import com.cci.kangdao.entity.WorkOrderFlow;
import com.cci.kangdao.escalation.dao.EscalationOrderTDao;
import com.cci.kangdao.escalation.model.EscalationOrderT;
import com.cci.kangdao.escalation.service.EscalationService;
import com.cci.kangdao.message.MessagePushUtils;
import com.cci.kangdao.model.DiagnoseConclusionInfo;
import com.cci.kangdao.model.TimeoutDic;
import com.cci.kangdao.model.condition.CloseWorkOrderCondition;
import com.cci.kangdao.model.condition.RefuseCloseWorkOrderCondition;
import com.cci.kangdao.redis.RedisClientUtils;
import com.cci.kangdao.service.*;
import com.cci.kangdao.utilTool.*;
import com.cci.kangdao.wechatOrder.service.IOrderPushMessageService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gexin.fastjson.JSON;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

//工单类接口实现类
@Service("WorkOrderTService")
public class WorkOrderTServiceImpl implements WorkOrderTService {

	private Logger log = Logger.getLogger(this.getClass().getName());

	@Autowired
	private WorkOrderTDao workOrderTDao;

	@Autowired
	private LoginDao loginDao;

	@Autowired
	private UserTDao userTDao;

	@Autowired
	private PositionUserTDao positionUserTDao;

	@Resource
	private WorkOrderRepairDao workOrderRepairDao;

	@Autowired
	private ServiceStationDao serviceStationDao;

	@Autowired
	private SSRepairTDao sSRepairTDao;

	@Resource
	private AppVersionTDao appVersionTDao;

	@Autowired
	private CompanyTDao companyTDao;

	@Autowired
	private CRMPlatformServiceDao platformServiceDao;

	@Autowired
	private WorkOrderPrincipalTDao workOrderPrincipalTDao;

	@Autowired
	private RedisClientUtils redisClientUtils;

	@Resource
	private EngineMsgDao engineMsgDao;

	@Resource
	private EngineTypeTDao engineTypeTDao;

	@Resource
	private PropertiesUtils propertiesUtils;

	@Resource
	private DiagnoseConclusionTDao diagnoseConclusionTDao;

	@Resource
	private ConfirmationByServiceManagerDao confirmationByServiceManagerDao;

	@Resource
	private AllServiceStationDao allServiceStationDao;

	@Resource
	private WorkOrderSelfDiagnosticTDao workOrderSelfDiagnosticTDao;

	@Resource
	private CRMPlatformServiceDao crmPlatformServiceDao;

	@Resource
	private WorkOrderOperatorRelationDao operatorRelationDao;

	@Resource
	private NoticeService noticeService;

	@Resource
	private DBUMessageService dbuMessageService;

	@Resource
	private CRMPlatformServiceDao crmServiceDao;
	@Resource
	private EscalationService escalationService;
	@Resource
	private DictionariesTDao dictionariesTDao;
	@Resource
	private EscalationOrderTDao escalationOrderTDao;
	@Resource
	private WorkOrderFlowTDao workOrderFlowTDao;
	@Resource
	private WorkOrderPicsDao workOrderPicsDao;
	@Resource
	private SceneTechnicalConfirmationTDao sceneTechnicalConfirmationTDao;

	@Resource
	private SceneTechnicalConfirmationServiceImpl sceneTechnicalConfirmationServiceImpl;

	@Autowired
	private CCECDiagnoseRepairMsgTDao cCECDiagnoseRepairMsgTDao;

	@Autowired
	private MessagePushUtils messagePushUtils;
	@Resource
	private IOrderPushMessageService iOrderPushMessageService;

	@Resource
	private WorkOrderDrDao workOrderDrDao;

	@Resource
	private PictureManagementTDao pictureManagementTDao;

	@Resource
	private UploadPicturesImpl uploadPicturesImpl;
	@Autowired
	private OutRangeTDao outRangeTDao;
	@Autowired
	private OutRangeFlowDao outRangeFlowDao;
	@Autowired
	private OutRangePrincipalDao outRangePrincipalDao;
	@Resource
	private DBUStrongRelationCDSConfigTDao dbuStrongRelationCDSConfigTDao;
	@Resource
	private ExceptionDataSyncCrmTDao exceptionDataSyncCrmTDao;
	@Resource
	private EngineMasterDataMapper engineMasterDataMapper;

	@Resource
	private ApprovalGoingOutTService approvalGoingOutTService;

	@Resource
	private OcrOrderVehicleLicenseRecordMapper ocrOrderVehicleLicenseRecordTMapper;
	@Lazy
	@Autowired
	private CRMServiceApiImpl crmServiceApi;
	@Resource
	private WorkOrderReasonTimeoutRecordTMapper workOrderReasonTimeoutRecordTMapper;

	private String msgbodyCCEC = "您有工单待400审核，工单号%s，请尽快处理！";
	// sprint18 XCEC外出审批消息格式更新
	private String xcecOverTimeBody = "外出审批提醒：%s服务商，工单号%s，外出里程%skm，请尽快审批。";
	// sprint18 XCEC区域经理接收重大故障提醒短信
	private String xcecFaultTypeStr = "重大故障提醒：%s服务商，发动机号%s，现有重大故障工单，请尽快处理";

	//服务站站长和服务站信息员和服务技师关闭工单
	@Override
	@Transactional
	public BaseResponse updateCloseWorkOrderById(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			//使用到手机端传来的map中字段有ID(工单主键id),CloseReason(关闭工单原因),serviceStationId(服务站id)
			CompanyT ccecChannelCompany = companyTDao.getCompanyInfoByCompanyNo("CCEC");
			CompanyT xcecChannelCompany = companyTDao.getCompanyInfoByCompanyNo("XCEC");
			JSONObject obj = new JSONObject();
			String workOrderId = (String) map.get("ID");
			String closeReason = (String) map.get("CloseReason");
			// 站点id不传，有工单id，根据工单id查找站点id。
//			String serviceStationId = (String) map.get("serviceStationId");
//			map.put("ServiceStationID", serviceStationId);
			map.put("OldUpdateTime", (String) map.get("updateTime"));
			String userADId = AESTool.decryptString(request.getHeader("userid"));//解密userid
			//UserT loginUserT = loginDao.getUserByid(userADId);
			UserT loginUserT = UserThreadLocal.get();
			long userid = loginUserT.getId();
			//SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			if ("".equals(workOrderId) || workOrderId == null) {
				return BaseResponse.error("工单id不能为空!");
			}
			//根据工单id获取工单信息
			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTById(map);
			if ((null == workOrderT.getIsTechSupport() || workOrderT.getIsTechSupport() != 1) && StringUtils.isBlank(closeReason)) {
				return BaseResponse.error("关闭工单原因不能为空!");
			}

			if (workOrderT.getOrderStatus() == 16 || workOrderT.getOrderStatus() == 31) {
				return BaseResponse.error("工单已被关闭!");
			}
			int orderStatus = 16;
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId() || workOrderT.getOrderChannel() == 1) {
				orderStatus = 31;
			}
			//把关闭工单的信息详情同步到CRM
			Map<String, Object> parameters = new HashMap<String, Object>();
			parameters.put("orderNo", workOrderT.getOrderNo());
			parameters.put("billStatus", orderStatus);
			parameters.put("actionTime", currentTime);
			parameters.put("directorName", loginUserT.getContact());
			parameters.put("directorPhone", loginUserT.getPhone());
			parameters.put("refuseReason", closeReason);
			parameters.put("phoneIMEI", MapUtils.getString(map, "IMEI", ""));
			parameters.put("positionLat", MapUtils.getFloatValue(map, "LocLat", 0));
			parameters.put("positionLon", MapUtils.getFloatValue(map, "LocLon", 0));
			parameters.put("location", MapUtils.getString(map, "Location", ""));
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
				if (map.containsKey("roleNo") && "R0033".equals(MapUtils.getString(map, "roleNo", ""))) {
					//2.8.0需求    增加角色编号  如果是该工单是ccec渠道并且是技师异常关闭   则把手机串号传给crm
					parameters.put("imei", MapUtils.getString(map, "IMEI", ""));
				}
				parameters.put("CCSSComplainerOrderNo", workOrderT.getOrderNoCrm());
				parameters.put("CCSSOrderNo", workOrderT.getCCSSOrderNo());
				parameters.put("customerName", workOrderT.getCustomerName());
				parameters.put("customerPhone", workOrderT.getCustomerPhone());
				parameters.put("customerCompany", workOrderT.getCustomerCompanyName());
				parameters.put("faultDesc", workOrderT.getCustomerComplaint());
				Map<String, Object> sSRepair = serviceStationDao.getStationNoAndNameByStationIdAndCompanyId(
						workOrderT.getServiceStationId(), workOrderT.getOrderChannel());
				if (org.apache.commons.collections.MapUtils.isNotEmpty(sSRepair)) {
					parameters.put("stationNo", sSRepair.get("BusinessNo"));
					parameters.put("stationName", sSRepair.get("StationName"));
				} else {
					parameters.put("stationNo", "");
					parameters.put("stationName", "");
				}
			}
			//  dcec   {"status":"1","msg":"当前工单【WO202404250587】下存在未取消的调件申请，无法进行异常关闭！、"}     需要先同步判断是否发可以关闭
			if (workOrderT.getOrderChannel()==3) {
				try {
					CRMResponeEntity cRMResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
							companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
							platformServiceDao, redisClientUtils, parameters,null);
					if (cRMResponeEntity.getStatus() != 0) {
						log.error("同步工单状态至CRM失败!状态:" + cRMResponeEntity.getStatus() + ",错误信息:"
								+ cRMResponeEntity.getMessage().replaceAll("、",""));
					}
					if(cRMResponeEntity.getStatus()==-999){
						return BaseResponse.error(-999,cRMResponeEntity.getMessage().replaceAll("、","")+"如有疑问可联系客服400-8809119");
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
					return BaseResponse.error(-998,"调取SF接口失败，请重试异常关闭或者联系客服400-8809119");
				}
			}

			Long serviceStationId = workOrderT.getServiceStationId();
			map.put("serviceStationId", workOrderT.getServiceStationId());
			map.put("ServiceStationID", workOrderT.getServiceStationId());
			// DCEC,XCEC服务站人员点击异常关闭 工单状态都是异常关闭16
			// DBU,CCEC服务站人员点击异常关闭 工单状态是异常关闭申请中31 2.8.0运维需求

			map.put("CloseTime", currentTime);
			map.put("Updator", userid);
			map.put("UpdateTime", currentTime);
			map.put("OrderStatus", orderStatus);
			if(null != workOrderT && workOrderT.getOrderStatus() == 2){
				map.put("isShowStation", -1);
			} else {
				map.put("isShowStation", 0);
			}
			//修改并保存工单状态
			int updateNum = workOrderTDao.updateCloseIsShowWorkOrderById(map);
			if (updateNum == 0) { // 工单状态没修改成功
				return BaseResponse.error(SMSEnum.type21.getIndex(), SMSEnum.type21.getName());
			}

			//插入并保存工单操作记录表数据
			Map<String, Object> workOrderFlowTMap = new HashMap<String, Object>(); //新建工单操作记录对象
			workOrderFlowTMap.put("OrderId", Long.parseLong(workOrderId));
			workOrderFlowTMap.put("ProcessorId", userid);
			workOrderFlowTMap.put("OrderStatus", orderStatus); //异常关闭
			workOrderFlowTMap.put("ProcessComment", closeReason);
			workOrderFlowTMap.put("ProLocLon", /*Float.parseFloat((String) map.get("LocLon"))*/MapUtils.getFloatValue(map,"LocLon",  0));
			workOrderFlowTMap.put("ProLocLat", /*Float.parseFloat((String) map.get("LocLat"))*/MapUtils.getFloatValue(map,"LocLat",  0));
			workOrderFlowTMap.put("ProLocation", map.get("Location"));
			workOrderFlowTMap.put("IMEI", map.get("IMEI")); //手机串号
			workOrderFlowTMap.put("Flag", 0);
			workOrderFlowTMap.put("Creator", userid);
			workOrderFlowTMap.put("CreateTime", currentTime);
			//大区经理审批，服务经理不可见
			if(null != workOrderT && workOrderT.getIsTechSupport() == 1 && workOrderT.getOrderStatus() == 2){
				workOrderFlowTMap.put("IsShowManager", 0);
			}
			workOrderRepairDao.saveOperation(workOrderFlowTMap); // 插入并保存工单操作记录数据

			// 工单异常关闭，判断是否有正在审批中的超距离申请，有的话置为失效状态
			String countSQL = "SELECT COUNT(*) FROM OutRange_T WHERE OrderId = %d AND Flag = 0 AND Status <=20";
			int outRangeCount = outRangeTDao.countBySQL(String.format(countSQL, Long.parseLong(workOrderId)));
			if (outRangeCount > 0) {
				// 如果已有超距离申请，则将申请的状态改为已失效。插入超距离申请操作记录。
				OutRangeT outRangeT = outRangeTDao.getOutRangeTByOrderId(Long.parseLong(workOrderId));
				// 申请状态标记10、待一网站长审核20、待区域经理审核30、终审通过40、一网站长审核不通过50、区域经理审核不通过60、已失效
				int status = outRangeT.getStatus();
				outRangeT.setStatus(60);// 已失效
				outRangeT.setUpdator(userid);
				outRangeT.setUpdateTime(LocalTimeUtil.getRealCurrentTime());
				outRangeTDao.updateSelective(outRangeT);
				// 插入超范围服务申请操作记录表
				OutRangeFlow outRangeFlow = new OutRangeFlow();
				outRangeFlow.setOutRangeId(outRangeT.getId());// 超范围服务申请表ID
				outRangeFlow.setAction(4);// 行为动作1、提交申请2、审批通过3、审批不通过4、异常关闭
				outRangeFlow.setNextStatus(outRangeT.getStatus());// 操作后的申请状态标记
				outRangeFlow.setFlag(0);
				outRangeFlow.setCreator(userid);
				outRangeFlow.setCreateTime(LocalTimeUtil.getRealCurrentTime());
				outRangeFlowDao.insertSelective(outRangeFlow);
				List<OutRangePrincipal> outRangePrincipals = outRangePrincipalDao
						.getOutRangePrincipalByOutRangeId(outRangeT.getId(), status);
				for (OutRangePrincipal outRangePrincipal : outRangePrincipals) {
					// 异常关闭
					String smsText = "您有超距离审批单，因服务工单异常关闭，无需审批，状态变更已失效，工单号：%s。";
					// 'Function',28,'电子围栏申请状态变更提醒'
					// 'Category',6,'提交申请提醒'
					// 'Category',7,'审批通过提醒'
					// 'Category',8,'审批拒绝提醒'
					// 'Category',9,'已失效提醒'
					noticeService.sendSMS(28, 8, outRangeT.getOrderId(), outRangePrincipal.getPrincipalId(), null,
							String.format(smsText, workOrderT.getOrderNo()), userid);
				}

			}

			// 插入并保存消息提醒表数据
			// 新建消息提醒表对象list(可能会推送多人短信提醒)
			List<Map<String, Object>> notifyRecordTMapList = new ArrayList<Map<String, Object>>();
			map.put("ADUserID", userADId);
			map.put("CompanyID", workOrderT.getOrderChannel()); //getPostUserTByServiceStationIdCompanyId方法中map需要CompanyID字段
			if (workOrderT != null) {
				String ccecSmstext = "您有工单申请异常关闭，工单号%s，请查看。";
				String dbuSmstext = "您有工单申请异常关闭，工单号" + workOrderT.getOrderNo() +"，属于\"" + workOrderT.getSellType() + "\"" + (StringUtils.isNotBlank(workOrderT.getServiceSubtype()) ? "-" + workOrderT.getServiceSubtype() : "") + "，请查看。";
				String closeReasonText = "";
				if(StringUtils.isNotBlank(closeReason)){
					closeReasonText = ",异常关闭原因" + closeReason;
				}
				String smstext = "您有工单被异常关闭" + closeReasonText + "，工单号" + workOrderT.getOrderNo() + "，请查看！";
				String msg = workOrderT.getOrderNo();
				if (StringUtils.isNotEmpty(workOrderT.getCCSSOrderNo())) {
					msg += "（FW号" + workOrderT.getCCSSOrderNo() + "）";
				}
				ccecSmstext = String.format(ccecSmstext, msg);
				if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) { //ccec渠道工单  重新赋值提示语
					smstext = ccecSmstext;
				}
				if (workOrderT.getOrderChannel() == 1) { //dbu渠道工单  重新赋值提示语
					smstext = dbuSmstext;
				}
				if(workOrderT.getOrderStatus() != 2){
					//获取这条工单的相关主副服务技师
					map.put("ID", Long.parseLong(map.get("ID").toString()));
					List<UserT> fWJSUserList = userTDao.getUserTByServiceStationIdWorkOrderId(map);
					if (CollectionUtils.isNotEmpty(fWJSUserList)) {
						for (UserT userT : fWJSUserList) {
							if (userT != null) {
								if (userT.getIsPrincipal() == 1) {
									if (userT.getId() == userid) {
										continue;
									}
									String FFJSphone = userT.getPhone(); //服务技师手机号
									SmsUtils.sendMessage(FFJSphone, smstext);
									Map<String, Object> FFJSNotifyRecordTMap = new HashMap<String, Object>();
									FFJSNotifyRecordTMap.put("OrderId", workOrderId);
									FFJSNotifyRecordTMap.put("Function", 10); //工单异常关闭提醒
									FFJSNotifyRecordTMap.put("Category", 5); //工单异常关闭提醒
									FFJSNotifyRecordTMap.put("ReceiverId", userT.getId()); //接收人
									FFJSNotifyRecordTMap.put("Content", smstext);
									FFJSNotifyRecordTMap.put("SendType", 1);
									FFJSNotifyRecordTMap.put("SendTime", currentTime);
									FFJSNotifyRecordTMap.put("Status", 1);
									FFJSNotifyRecordTMap.put("ExceptionInfo", "");
									FFJSNotifyRecordTMap.put("IsRead", 0);
									FFJSNotifyRecordTMap.put("Flag", 0);
									FFJSNotifyRecordTMap.put("Creator", userid);
									FFJSNotifyRecordTMap.put("CreateTime", currentTime);
									notifyRecordTMapList.add(FFJSNotifyRecordTMap);
									//推送App提醒消息
									noticeService.push(10, 5, Long.valueOf(workOrderId), userT.getId(), userT.getUserName(),
											"工单异常关闭提醒", smstext, smstext, userid);
								}
							}
						}
					}
					// 获取所有的站长与信息员信息(如果是二网，则一网二网站长都推消息)
					List<UserT> ZZuserTList = userTDao.getStationMasterListByServiceStationId(serviceStationId);
					ZZuserTList.addAll(userTDao.getStationMangerListByChildSSId(serviceStationId));

					if (CollectionUtils.isNotEmpty(ZZuserTList)) {
						Map<Object, Boolean> seen = new ConcurrentHashMap<>();
						ZZuserTList = ZZuserTList.stream()
								.filter(user -> seen.putIfAbsent(user.getId(), Boolean.TRUE) == null)
								.collect(Collectors.toList());// 去重
						for (UserT userT : ZZuserTList) {
							String ZZphone = userT.getPhone(); //站长手机号
							if (userT.getId() == userid) {
								continue;
							}
							SmsUtils.sendMessage(ZZphone, smstext);
							Map<String, Object> FWZZNotifyRecordTMap = new HashMap<String, Object>();
							FWZZNotifyRecordTMap.put("OrderId", workOrderId);
							FWZZNotifyRecordTMap.put("Function", 10); //工单异常关闭提醒
							FWZZNotifyRecordTMap.put("Category", 5); //工单异常关闭提醒
							FWZZNotifyRecordTMap.put("ReceiverId", userT.getId()); //接收人
							FWZZNotifyRecordTMap.put("Content", smstext);
							FWZZNotifyRecordTMap.put("SendType", 1); //短信推送
							FWZZNotifyRecordTMap.put("SendTime", currentTime);
							FWZZNotifyRecordTMap.put("Status", 1);
							FWZZNotifyRecordTMap.put("ExceptionInfo", "");
							FWZZNotifyRecordTMap.put("IsRead", 0);
							FWZZNotifyRecordTMap.put("Flag", 0);
							FWZZNotifyRecordTMap.put("Creator", userid);
							FWZZNotifyRecordTMap.put("CreateTime", currentTime);
							notifyRecordTMapList.add(FWZZNotifyRecordTMap);

							//推送App提醒消息
							noticeService.push(10, 5, Long.valueOf(workOrderId), userT.getId(), userT.getUserName(),
									"工单异常关闭提醒", smstext, smstext, userid);
						}
					}
				}

				Map<String, Object> qygcsMap = new HashMap<>();
				if (workOrderT.getOrderChannel() == 1) { //DBU需求，只给指定的区域工程师推送消息
					qygcsMap = positionUserTDao.getDBUAreaManager(workOrderT.getId());
				}

				//获取所有区域服务经理手机号
				//根据服务站id和服务渠道id获取区域服务经理手机号
				/**
				 * 20210812 【短信通知】【XCEC】短信通知取消 取消以下短信发送： 1）区域经理 新工单提醒 实时发送：您有新工单信息，工单号XXX，请查看。
				 * 2）区域经理 新工单提醒（400指派给区域服务经理）实时发送：您有新工单信息，工单号XXX，请尽快处理。 3）区域经理 工单接受提醒
				 * 实时发送：您有工单被接受，工单号XXX，请查看。 4）区域经理 技师接单提醒 实时发送：您有工单被接单，工单号XXX，请查看。 5）区域经理
				 * 技师已出发提醒 实时发送：您的工单服务技师已出发，工单号XXX，请查看。 6）区域经理 技师开始维修提醒
				 * 实时发送：您的工单服务技师开始维修，工单号XXX，请查看。 7）区域经理 工单取消提醒 实时发送：您有工单取消，工单号XXX，请查看。 8）区域经理
				 * 服务商关闭工单提醒 实时发送：您有工单被关闭，工单号XXX，请查看。 - 当前，仅为R0041和R0069的人员，并不包含区域服务经理
				 */
				List<PositionUserT> positionUserTList = new ArrayList<>();
				if (1==workOrderT.getIsTechSupport()) {
					positionUserTList = positionUserTDao.getManager(map);
				}else {
					positionUserTList = positionUserTDao
							.getPostUserTListByServiceStationIdCompanyId(map);
					positionUserTList.addAll(positionUserTDao.getPostUserTListByChildStationIdCompanyId(map));
				}
				if (CollectionUtils.isNotEmpty(positionUserTList)) {
					Map<Object, Boolean> seen = new ConcurrentHashMap<>();
					positionUserTList = positionUserTList.stream()
							.filter(position -> seen.putIfAbsent(position.getUserPhone(), Boolean.TRUE) == null)
							.collect(Collectors.toList());// 去重
					for (PositionUserT positionUserT : positionUserTList) {
						String QYFWJLphone = positionUserT.getUserPhone(); //区域服务经理手机号
						if (workOrderT.getOrderChannel() == 1 && MapUtils.isNotEmpty(qygcsMap)) {
							//拿dbu指定的区域工程师手机号和上面的区域工程师集合循环比较，比较到了则推送，其他渠道工单不走此逻辑
							if (!(MapUtils.getString(qygcsMap, "DBEngineerPhone", "")
									.equals(positionUserT.getUserPhone()))) {
								continue;
							}
						}
						List<UserT> qyfwjlList = loginDao.getUserByPhone(QYFWJLphone);
						if (workOrderT.getOrderChannel() != xcecChannelCompany.getId()) {
							SmsUtils.sendMessage(QYFWJLphone, smstext);
							Map<String, Object> FWJLNotifyRecordTMap = new HashMap<String, Object>();
							FWJLNotifyRecordTMap.put("OrderId", workOrderId);
							FWJLNotifyRecordTMap.put("Function", 10); //工单异常关闭提醒
							FWJLNotifyRecordTMap.put("Category", 5); //工单异常关闭提醒
							if (CollectionUtils.isNotEmpty(qyfwjlList)) {
								FWJLNotifyRecordTMap.put("ReceiverId", qyfwjlList.get(0).getId()); //接收人
								FWJLNotifyRecordTMap.put("ExceptionInfo", "");
							} else {
								FWJLNotifyRecordTMap.put("ReceiverId", 0); //接收人
								FWJLNotifyRecordTMap.put("ExceptionInfo", "未查询到该用户");
							}
							FWJLNotifyRecordTMap.put("Content", smstext);
							FWJLNotifyRecordTMap.put("SendType", 1);
							FWJLNotifyRecordTMap.put("SendTime", currentTime);
							FWJLNotifyRecordTMap.put("Status", 1);
							FWJLNotifyRecordTMap.put("IsRead", 0);
							FWJLNotifyRecordTMap.put("Flag", 0);
							FWJLNotifyRecordTMap.put("Creator", userid);
							FWJLNotifyRecordTMap.put("CreateTime", currentTime);
							notifyRecordTMapList.add(FWJLNotifyRecordTMap);
						}
						//推送App提醒消息
						if (CollectionUtils.isNotEmpty(qyfwjlList)) {
							UserT qyfwjl = qyfwjlList.get(0);
							noticeService.push(10, 5, Long.valueOf(workOrderId), qyfwjl.getId(), qyfwjl.getUserName(),
									"工单异常关闭提醒", smstext, smstext, userid);
						}
					}
				}

				//因为ccec和dbu站长信息员和技师点击异常关闭改为异常关闭申请中，所以这块不再推送给用户异常关闭消息  2.8.0运维
				if (workOrderT.getOrderChannel() != ccecChannelCompany.getId() && workOrderT.getOrderChannel() != 1) {
					// 获取用户手机号
					// String ccecYHsmstext = "您有工单被关闭，工单号" + workOrderT.getOrderNo() + "，请查看。";
					/*
					 * if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
					 * //ccec渠道，提示语重新赋值 smstext = ccecYHsmstext; }
					 */
					String YHphone = workOrderT.getCustomerPhone(); // 用户手机号
					SmsUtils.sendMessage(YHphone, smstext);
					//先判断用户手机号是否在app中注册过，如果有拿出用户id
					List<UserT> userTs = loginDao.getUserByPhone(YHphone);
					Map<String, Object> userNotifyRecordTMap = new HashMap<String, Object>();
					userNotifyRecordTMap.put("OrderId", workOrderId);
					userNotifyRecordTMap.put("Function", 10); //工单异常关闭提醒
					userNotifyRecordTMap.put("Category", 5); //工单异常关闭提醒
					if (CollectionUtils.isNotEmpty(userTs)) {
						userNotifyRecordTMap.put("ReceiverId", userTs.get(0).getId()); //接收人
						userNotifyRecordTMap.put("ExceptionInfo", "");
					} else {
						userNotifyRecordTMap.put("ReceiverId", 0); //接收人
						userNotifyRecordTMap.put("ExceptionInfo", "未查询到该用户");
					}
					userNotifyRecordTMap.put("Content", smstext);
					userNotifyRecordTMap.put("SendType", 1);
					userNotifyRecordTMap.put("SendTime", currentTime);
					userNotifyRecordTMap.put("Status", 1);
					userNotifyRecordTMap.put("IsRead", 0);
					userNotifyRecordTMap.put("Flag", 0);
					userNotifyRecordTMap.put("Creator", userid);
					userNotifyRecordTMap.put("CreateTime", currentTime);
					notifyRecordTMapList.add(userNotifyRecordTMap);
					//推送App提醒消息
					if (CollectionUtils.isNotEmpty(userTs)) {
						noticeService.push(10, 5, Long.valueOf(workOrderId), userTs.get(0).getId(),
								userTs.get(0).getUserName(), "工单异常关闭提醒", smstext, smstext, userid);
					}
				}
			}
			if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
				workOrderRepairDao.saveMsgOperation(notifyRecordTMapList); //插入并保存消息提醒数据
			}
			if (workOrderT.getOrderChannel()!=3) {
				try {
					CRMResponeEntity cRMResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
							companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
							platformServiceDao, redisClientUtils, parameters,null);
					if (cRMResponeEntity.getStatus() != 0) {
						log.error("同步工单状态至CRM失败!状态:" + cRMResponeEntity.getStatus() + ",错误信息:"
								+ cRMResponeEntity.getMessage());
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
				}
			}


            //dcec的工单需要推送公众号消息   dcec微信公众号查看工单详情url
            Integer orderSource;
            try {
                orderSource = workOrderT.getOrderSource();
                if (workOrderT.getOrderChannel() == 3 && orderSource == 6) {
                    String dbuWechatWorkOrderInfoUrl = propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
                    //拼公众号中查看详情的url
                    String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, workOrderT.getId());
                    //推送微信公众号消息
                    String firstData = "您有一条重要的工单状态信息";
                    String keyWord1 = "编号：" + workOrderT.getOrderNo();
					String closeReasonText = "";
					if(StringUtils.isNotBlank(closeReason)){
						closeReasonText = ",异常关闭原因" + closeReason;
					}
                    String keyWord2 = "您有工单被异常关闭" + closeReasonText + "，请查看！";
                    String keyWord3 = Dictionaries.OrderStatus_16.getName();
                    String keyWord4 = UserThreadLocal.get().getContact();
                    String remark = "请点击详情查看工单内容";
                    //########################
                    iOrderPushMessageService.sendOrderMessage(workOrderT.getId(), urlFormat, firstData, keyWord1,
                            keyWord2, keyWord3, keyWord4, remark);

				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			// DBU渠道关闭工单需要调用关闭主动升级工单接口
			// 1: 服务工单异常关闭
			// 2: 服务工单已取消
			// 3: 服务工单已完成
			// 2.8.0运维去掉这块 因为dbu异常关闭改为异常关闭申请中，所以这块逻辑需要放到审核通过
			/*
			 * if (workOrderT.getOrderChannel() == 1) {
			 * escalationService.disableEscalationByWorkOrderId(workOrderT.getId(), 1); }
			 */
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
			return BaseResponse.error("未知错误面！");
		}
		return BaseResponse.success("关闭工单成功");
	}

	//区域工程师关闭工单
	@Override
	@Transactional
	public ModelAndView areaEngineerCloseWorkOrder(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			//使用到手机端传来的map中字段有ID(工单主键id),CloseReason(关闭工单原因)
			JSONObject obj = new JSONObject();
			String workOrderId = (String) map.get("ID");
			String closeReason = (String) map.get("CloseReason");
			map.put("OldUpdateTime", (String) map.get("updateTime"));
			String userADId = AESTool.decryptString(request.getHeader("userid"));//解密userid
			UserT loginUserT = loginDao.getUserByid(userADId);
			long userid = loginUserT.getId();
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			if ("".equals(workOrderId) || workOrderId == null) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if ("".equals(closeReason) || (closeReason) == null) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "关闭工单原因不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			//根据工单id获取工单信息
			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTById(map);
			//插入并保存工单操作记录表数据
			Map<String, Object> workOrderFlowTMap = new HashMap<String, Object>(); //新建工单操作记录对象
			workOrderFlowTMap.put("OrderId", Long.parseLong(workOrderId));
			workOrderFlowTMap.put("ProcessorId", userid);
			workOrderFlowTMap.put("OrderStatus", 21); //异常关闭
			workOrderFlowTMap.put("ProcessComment", closeReason);
			workOrderFlowTMap.put("ProLocLon", /*Float.parseFloat((String) map.get("LocLon"))*/MapUtils.getFloatValue(map,"LocLon",  0));
			workOrderFlowTMap.put("ProLocLat", /*Float.parseFloat((String) map.get("LocLat"))*/MapUtils.getFloatValue(map,"LocLat",  0));
			workOrderFlowTMap.put("ProLocation", map.get("Location"));
			workOrderFlowTMap.put("IMEI", map.get("IMEI")); //手机串号
			workOrderFlowTMap.put("Flag", 0);
			workOrderFlowTMap.put("Creator", userid);
			workOrderFlowTMap.put("CreateTime", currentTime);
			workOrderRepairDao.saveOperation(workOrderFlowTMap); //插入并保存工单操作记录数据
			//插入并保存消息提醒表数据
			//新建消息提醒表对象list(可能会推送多人短信提醒)
			List<Map<String, Object>> notifyRecordTMapList = new ArrayList<Map<String, Object>>();
			if (null != workOrderT) {
				String smstext = "您有工单被异常关闭，异常关闭原因" + closeReason + "，工单号" + workOrderT.getOrderNo() + "，请查看！";
				//获取用户手机号
				String YHphone = workOrderT.getCustomerPhone(); //用户手机号

				/**
				 * 2.10.0服务工单异常关闭后，暂停对用户的消息推送(短信和app),只做消息记录
				 */
				//SmsTool.sendSms(YHphone, smstext);


				//先判断用户手机号是否在app中注册过，如果有拿出用户id
				List<UserT> userTs = loginDao.getUserByPhone(YHphone);
				Map<String, Object> userNotifyRecordTMap = new HashMap<String, Object>();
				userNotifyRecordTMap.put("OrderId", workOrderId);
				userNotifyRecordTMap.put("Function", 10); //工单异常关闭提醒
				userNotifyRecordTMap.put("Category", 5); //工单异常关闭提醒
				if (CollectionUtils.isNotEmpty(userTs)) {
					userNotifyRecordTMap.put("ReceiverId", userTs.get(0).getId()); //接收人
					userNotifyRecordTMap.put("ExceptionInfo", "");
				} else {
					userNotifyRecordTMap.put("ReceiverId", 0); //接收人
					userNotifyRecordTMap.put("ExceptionInfo", "未查询到该用户");
				}
				userNotifyRecordTMap.put("Content", smstext);
				userNotifyRecordTMap.put("SendType", 1);
				userNotifyRecordTMap.put("SendTime", currentTime);
				userNotifyRecordTMap.put("Status", 1);
				userNotifyRecordTMap.put("IsRead", 0);
				userNotifyRecordTMap.put("Flag", 0);
				userNotifyRecordTMap.put("Creator", userid);
				userNotifyRecordTMap.put("CreateTime", currentTime);
				notifyRecordTMapList.add(userNotifyRecordTMap);
				//推送App提醒消息
				if (CollectionUtils.isNotEmpty(userTs)) {
					noticeService.pushUser(10, 5, Long.valueOf(workOrderId), userTs.get(0).getId(),
							userTs.get(0).getUserName(), "工单异常关闭提醒", smstext, smstext, userid);
				}
				if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
					workOrderRepairDao.saveMsgOperation(notifyRecordTMapList); //插入并保存消息提醒数据
				}
			}

			// dbu的工单需要推送公众号消息 dbu微信公众号查看工单详情url
			/*
			 * if (workOrderT.getOrderChannel() == 1) { String dbuWechatWorkOrderInfoUrl =
			 * propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
			 * //拼公众号中查看详情的url String urlFormat = String.format(dbuWechatWorkOrderInfoUrl,
			 * workOrderT.getId()); //推送微信公众号消息 String firstData = "您有一条重要的工单状态信息"; String
			 * keyWord1 = "编号：" + workOrderT.getOrderNo(); String keyWord2 =
			 * "您有工单被异常关闭，异常关闭原因" + closeReason + "，请查看！"; String keyWord3 =
			 * Dictionaries.OrderStatus_16.getName(); String keyWord4 =
			 * UserThreadLocal.get().getContact(); String remark = "请点击详情查看工单内容"; try {
			 * iOrderPushMessageService.sendOrderMessage(workOrderT.getId(), urlFormat,
			 * firstData, keyWord1, keyWord2, keyWord3, keyWord4, remark); } catch
			 * (Exception e) { e.printStackTrace(); } }
			 */

            //dcec的工单需要推送公众号消息   dcec微信公众号查看工单详情url
            Integer orderSource;
            try {
                orderSource = workOrderT.getOrderSource();
                if (workOrderT.getOrderChannel() == 3 && orderSource == 6) {
                    String dbuWechatWorkOrderInfoUrl = propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
                    //拼公众号中查看详情的url
                    String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, workOrderT.getId());
                    //推送微信公众号消息
                    String firstData = "您有一条重要的工单状态信息";
                    String keyWord1 = "编号：" + workOrderT.getOrderNo();
                    String keyWord2 = "您有工单被异常关闭，异常关闭原因" + closeReason + "，请查看！";
                    String keyWord3 = Dictionaries.OrderStatus_16.getName();
                    String keyWord4 = UserThreadLocal.get().getContact();
                    String remark = "请点击详情查看工单内容";
                    //########################
                    iOrderPushMessageService.sendOrderMessage(workOrderT.getId(), urlFormat, firstData, keyWord1,
                            keyWord2, keyWord3, keyWord4, remark);

                }
            } catch (Exception e) {
                e.printStackTrace();
            }

			map.put("CloseTime", currentTime);
			map.put("Updator", userid);
			map.put("UpdateTime", currentTime);
			map.put("OrderStatus", 21);
			//修改并保存工单状态
			int updateNum = workOrderTDao.updateCloseWorkOrderById(map);
			if (updateNum == 0) { //工单状态没修改成功
				obj.put("status", SMSEnum.type21.getIndex());
				obj.put("msg", SMSEnum.type21.getName());
				obj.put("data", "");
				// 主动回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				//返回客户
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			//把关闭工单的信息详情同步到CRM
			Map<String, Object> parameters = new HashMap<String, Object>();
			parameters.put("orderNo", workOrderT.getOrderNo());
			parameters.put("billStatus", 21);
			parameters.put("actionTime", currentTime);
			parameters.put("directorName", loginUserT.getContact());
			parameters.put("directorPhone", loginUserT.getPhone());
			parameters.put("refuseReason", closeReason);
			try {
				CRMResponeEntity cRMResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
						companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
						platformServiceDao, redisClientUtils, parameters,null);
				if (cRMResponeEntity.getStatus() != 0) {
					log.error("同步工单状态至CRM失败!状态:" + cRMResponeEntity.getStatus() + ",错误信息:"
							+ cRMResponeEntity.getMessage());
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
			}
			obj.put("data", "");
			obj.put("status", 0);
			obj.put("msg", "关闭工单成功");
			ParameterTool.writeResponse(response, obj.toString());
			//DBU渠道关闭工单需要调用关闭主动升级工单接口
			//1: 服务工单异常关闭
			//2: 服务工单已取消
			//3: 服务工单已完成
			if (workOrderT.getOrderChannel() == 1) {
				escalationService.disableEscalationByWorkOrderId(workOrderT.getId(), 1);
			}
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	//服务站接受工单
	@Transactional
	@Override
	public ModelAndView receiveWorkOrder(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			// 使用到手机端传来的map中字段有是否外出(isOutside),工单id(ID),经度LocLon纬度，LocLat，故障地点Location手机串号IMEI，ServiceStationID(服务站id)
			JSONObject obj = new JSONObject(); // 声明返给前端json对象
			String IsOutside = (String) map.get("IsOutside"); // 接收是否外出字段
			String workOrderId = (String) map.get("ID"); // 接收工单id
			/*
			 * String userADId =
			 * AESTool.decryptString(request.getHeader("userid"));//解密userid UserT userT =
			 * loginDao.getUserByid(userADId);
			 */
			UserT userT = UserThreadLocal.get();
			Long userId = userT.getId(); //获取登陆人主键id
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			if ("".equals(workOrderId) || workOrderId == null) { //判断工单id是否为空
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTById(map); //获取工单信息
			CompanyT ccecChannelCompany = companyTDao.getCompanyInfoByCompanyNo("CCEC");
			CompanyT xcecChannelCompany = companyTDao.getCompanyInfoByCompanyNo("XCEC");
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId() && !map.containsKey("ServiceInitPlan")) {
				//ccec渠道需要校验   服务初始计划是否为空
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务初始计划不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (workOrderT.getOrderStatus() == 5) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单已被拒单!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (workOrderT.getOrderStatus() == 6) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单已被接单!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			//接受工单，修改工单表对应信息
			Map<String, Object> workOrderTMap = new HashMap<String, Object>(); //新建工单map对象
			if (!"".equals(IsOutside) && IsOutside != null) {
				workOrderTMap.put("IsOutside", Integer.parseInt(IsOutside)); //如果是否外出不为空就插入这个字段(1为是，0为否)
			}
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
				workOrderTMap.put("ServiceInitPlan", MapUtils.getString(map, "ServiceInitPlan")); //服务初始计划  ccec
			}
			workOrderTMap.put("ReceiveTimeStation", currentTime); //服务站接单时间
			workOrderTMap.put("OrderStatus", 6); //工单状态为待派服务技师
			workOrderTMap.put("Updator", userId); //修改人
			workOrderTMap.put("UpdateTime", currentTime); //修改时间
			workOrderTMap.put("ID", Long.parseLong(workOrderId)); //工单主键id
			workOrderTMap.put("oldUpdateTime", (String) map.get("updateTime")); //前端传来的这条工单的修改时间
			int updateNum = workOrderTDao.receiveWorkOrder(workOrderTMap); //保存修改的工单信息
			if (updateNum == 0) {
				obj.put("status", SMSEnum.type21.getIndex());
				obj.put("msg", SMSEnum.type21.getName());
				obj.put("data", "");
				//返回客户
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			//接受工单后推送短息给终端用户和区域服务经理
			map.put("ServiceStationID", workOrderT.getServiceStationId());
			map.put("CompanyID", workOrderT.getOrderChannel());
			//新建消息提醒表对象list(可能会推送多人短信提醒)
			List<Map<String, Object>> notifyRecordTMapList = new ArrayList<Map<String, Object>>();
			String customerPhoneString = workOrderT.getCustomerPhone(); //获取终端用户手机号
			ServiceStationT serviceStationT = serviceStationDao
					.findServiceStationByID(String.valueOf(workOrderT.getServiceStationId())); //获取服务站信息
			//推送短信给终端用户的消息
			List<Map<String, Object>> sSRepairTMapList = sSRepairTDao.getSSRepairTByServiceStationIDCompanyID(map); //拿到服务站热线电话
			String customertext = ""; //ccec提示给用户的消息
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
				customertext = "您的工单已有服务商接单，工单号" + workOrderT.getOrderNo() + "，请查看。"; //ccec提示给用户的消息
				//SmsTool.sendSms(customerPhoneString, customertext);   //调用短信接口推送短信
			} else {
				if (CollectionUtils.isNotEmpty(sSRepairTMapList)) {
					customertext = serviceStationT.getStationname() + "服务站已受理维修业务，" + "服务站热线电话"
							+ sSRepairTMapList.get(0).get("HotlineTel") + "，您同时也可通过应用商店搜索e路康明斯app查看进度！";
				}
			}
			SmsUtils.sendMessage(customerPhoneString, customertext); //调用短信接口推送短信
			List<UserT> userTs = loginDao.getUserByPhone(workOrderT.getCustomerPhone());
			//先判断用户手机号是否在app中注册过，如果有拿出用户id，如果没有就不插入消息推送记录表
			//声明终端用户消息推送记录表map对象
			Map<String, Object> userNotifyRecordTMap = new HashMap<String, Object>();
			userNotifyRecordTMap.put("OrderId", workOrderId);
			userNotifyRecordTMap.put("Function", 3); //服务商响应工单提醒
			userNotifyRecordTMap.put("Category", 1); //新工单提醒
			if (CollectionUtils.isNotEmpty(userTs)) {
				userNotifyRecordTMap.put("ReceiverId", userTs.get(0).getId());
				userNotifyRecordTMap.put("ExceptionInfo", "");
			} else {
				userNotifyRecordTMap.put("ReceiverId", 0);
				userNotifyRecordTMap.put("ExceptionInfo", "未查询到该用户");
			}
			userNotifyRecordTMap.put("Content", customertext);
			userNotifyRecordTMap.put("SendType", 1); //短信方式
			userNotifyRecordTMap.put("SendTime", currentTime);
			userNotifyRecordTMap.put("Status", 1);
			userNotifyRecordTMap.put("IsRead", 0);
			userNotifyRecordTMap.put("Flag", 0);
			userNotifyRecordTMap.put("Creator", userId);
			userNotifyRecordTMap.put("CreateTime", currentTime);

			notifyRecordTMapList.add(userNotifyRecordTMap); //把终端用户消息推送记录添加到消息提醒表对象list中
			//推送App提醒消息
			String content = "您有工单被接受，工单号" + workOrderT.getOrderNo() + "，请查看！";
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) { //ccec提示语不一样
				content = customertext;
			}
			if (CollectionUtils.isNotEmpty(userTs)) {
				noticeService.push(3, 1, Long.valueOf(workOrderId), userTs.get(0).getId(), userTs.get(0).getUserName(),
						"新工单提醒", content, content, userId);
			} else {
				noticeService.push(3, 1, Long.valueOf(workOrderId), 0L, "", "新工单提醒", content, content, userId);
			}

			//dbu的工单需要推送公众号消息   dbu微信公众号查看工单详情url
			if (workOrderT.getOrderChannel() == 1) {
				String dbuWechatWorkOrderInfoUrl = propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
				// Map<String, Object> weChatUserRelationTMap =
				// weChatUserRelationTDao.getWeChatUserRelationTByUserPhone(userTs.get(0).getPhone());
				// if (MapUtils.isNotEmpty(weChatUserRelationTMap)) {
				// 拼公众号中查看详情的url
				String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, workOrderId);
				// 推送微信公众号消息
				String firstData = "您有一条重要的工单状态信息";
				String keyWord1 = "编号：" + workOrderT.getOrderNo();
				String keyWord2 = "（" + serviceStationT.getStationname() + "服务商）已受理维修业务，服务商热线电话"
						+ sSRepairTMapList.get(0).get("HotlineTel") + "，您同时也可通过应用商店搜索e路康明斯app查看进度。";
				String keyWord3 = Dictionaries.OrderStatus_06.getName();
                String keyWord4 = UserThreadLocal.get().getContact();
                String remark = "请点击详情查看工单内容";
                iOrderPushMessageService.sendOrderMessage(Long.parseLong(workOrderId), urlFormat, firstData, keyWord1,
							keyWord2, keyWord3, keyWord4, remark);
				//}
			}

			//dcec的工单需要推送公众号消息   dcec微信公众号查看工单详情url

			Integer orderSource;
			try {
				orderSource = workOrderT.getOrderSource();
				if (workOrderT.getOrderChannel() == 3 && orderSource == 6) {
					String dbuWechatWorkOrderInfoUrl = propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
					//Map<String, Object> weChatUserRelationTMap = weChatUserRelationTDao.getWeChatUserRelationTByUserPhone(us.get(0).getPhone());
					//if (MapUtils.isNotEmpty(weChatUserRelationTMap)) {
					//拼公众号中查看详情的url
					String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, workOrderT.getId());
					//推送微信公众号消息
					String firstData = "您有一条重要的工单状态信息";
					String keyWord1 = "编号：" + workOrderT.getOrderNo();
					String keyWord2 = "（" + serviceStationT.getStationname() + "服务商）已受理维修业务，服务商热线电话" +
							sSRepairTMapList.get(0).get("HotlineTel") + "，您同时也可通过应用商店搜索e路康明斯app查看进度。";
					String keyWord3 = Dictionaries.OrderStatus_06.getName();
					String keyWord4 = UserThreadLocal.get().getContact();
					String remark = "请点击详情查看工单内容";
					//########################
					iOrderPushMessageService.sendOrderMessage(workOrderT.getId(), urlFormat, firstData, keyWord1,
							keyWord2, keyWord3, keyWord4, remark);

				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			if (workOrderT.getOrderChannel() != ccecChannelCompany.getId()) { //ccec渠道服务站接单和别的渠道推送消息逻辑不一样，ccec是只推送用户，已在上面推送，所以加此判断区分渠道
				Map<String, Object> qygcsMap = new HashMap<>();
				if (workOrderT.getOrderChannel() == 1) { //DBU需求，只给指定的区域工程师推送消息
					qygcsMap = positionUserTDao.getDBUAreaManager(workOrderT.getId());
				}
				//大工匠工单   应该发给  大区经理
				List<PositionUserT> positionUserTList = new ArrayList<>();
				if (1==workOrderT.getIsTechSupport()) {
					positionUserTList = positionUserTDao
							.getManager(map); //获取服务站对应的区域服务经理
				}else {
					positionUserTList = positionUserTDao
							.getPostUserTListByServiceStationIdCompanyId(map); //获取服务站对应的区域服务经理
				}
				//推送短信给区域服务经理的消息
				String JLtext = "您有工单被接受，工单号" + workOrderT.getOrderNo() + "，";
				if(workOrderT.getOrderChannel() == 1){
					JLtext = JLtext + "属于\"" + workOrderT.getSellType() + "\"" + (org.apache.commons.lang3.StringUtils.isNotBlank(workOrderT.getServiceSubtype()) ? "-" + workOrderT.getServiceSubtype() : "") + "，";
				}
				JLtext = JLtext + "请查看！";
				if (CollectionUtils.isNotEmpty(positionUserTList)) {
					for (PositionUserT positionUserT : positionUserTList) {
						/**
						 * 20210812 【短信通知】【XCEC】短信通知取消 取消以下短信发送： 1）区域经理 新工单提醒 实时发送：您有新工单信息，工单号XXX，请查看。
						 * 2）区域经理 新工单提醒（400指派给区域服务经理）实时发送：您有新工单信息，工单号XXX，请尽快处理。 3）区域经理 工单接受提醒
						 * 实时发送：您有工单被接受，工单号XXX，请查看。- 当前 4）区域经理 技师接单提醒 实时发送：您有工单被接单，工单号XXX，请查看。 5）区域经理
						 * 技师已出发提醒 实时发送：您的工单服务技师已出发，工单号XXX，请查看。 6）区域经理 技师开始维修提醒
						 * 实时发送：您的工单服务技师开始维修，工单号XXX，请查看。 7）区域经理 工单取消提醒 实时发送：您有工单取消，工单号XXX，请查看。 8）区域经理
						 * 服务商关闭工单提醒 实时发送：您有工单被关闭，工单号XXX，请查看。
						 */
						//如果是dbu的工单，并且能获取出来区域工程师
						if (workOrderT.getOrderChannel() == 1 && MapUtils.isNotEmpty(qygcsMap)) {
							//拿dbu指定的区域工程师手机号和上面的区域工程师集合循环比较，比较到了则推送，其他渠道工单不走此逻辑
							if (!(MapUtils.getString(qygcsMap, "DBEngineerPhone", "")
									.equals(positionUserT.getUserPhone()))) {
								continue;
							}
						}
						Boolean status = false; // 用于判断是否保存短信记录
						if ((null == xcecChannelCompany)
								|| (workOrderT.getOrderChannel() != xcecChannelCompany.getId())) {
							SmsUtils.sendMessage(positionUserT.getUserPhone(), JLtext); // 调用短信接口推送短信
							status = true;
						} else if (workOrderT.getOrderChannel() == xcecChannelCompany.getId()){
							// sprint18-【短信通知】【XCEC】短信通知修改
							// 2）现状：区域经理接收外出审批单提醒：服务站、用户和CAC创建外出工单成功且外出里程大于等于300公里（服务商位置和用户故障位置系统推荐最短里程）每10分钟发送一次提醒短信：您有未审批工单，工单号XXX，请尽快审批。三十分钟自动审核通过。
							// ---修改：①发送机制修改：创建当时实时发一次，第10分钟发一次，第20分钟发一次，第30分钟自动审批通过，共发三条短信。②短信模板修改：外出审批提醒：XX服务商，工单号xx，外出里程xxkm，请尽快审批。
							//大工匠工单  ---应该给  大区经理发送  所以去除大工匠工单
							if (1!=workOrderT.getIsTechSupport()&&1 == workOrderT.getIsOutside() && null != workOrderT.getGuessDistance()
									&& workOrderT.getGuessDistance() > 300D) {
								String xcecOutApplyStr = String.format(xcecOverTimeBody,
										serviceStationT.getStationname(), workOrderT.getOrderNo(),
										workOrderT.getGuessDistance());
								SmsUtils.sendMessage(positionUserT.getUserPhone(), xcecOutApplyStr); // 调用短信接口推送短信
								status = true;
							}
						}
						List<UserT> qyfwjls = loginDao.getUserByPhone(positionUserT.getUserPhone());
						if (status){
							//声明服务经理消息推送记录表map对象
							Map<String, Object> FWJLNotifyRecordTMap = new HashMap<String, Object>();
							FWJLNotifyRecordTMap.put("OrderId", workOrderId);
							FWJLNotifyRecordTMap.put("Function", 3); //服务商响应工单提醒
							FWJLNotifyRecordTMap.put("Category", 1); //新工单提醒
							if (CollectionUtils.isNotEmpty(qyfwjls)) {
								FWJLNotifyRecordTMap.put("ReceiverId", qyfwjls.get(0).getId());
								FWJLNotifyRecordTMap.put("ExceptionInfo", "");
							} else {
								FWJLNotifyRecordTMap.put("ReceiverId", 0);
								FWJLNotifyRecordTMap.put("ExceptionInfo", "未查询到该用户");
							}
							FWJLNotifyRecordTMap.put("Content", JLtext);
							FWJLNotifyRecordTMap.put("SendType", 1); //短信方式
							FWJLNotifyRecordTMap.put("SendTime", currentTime);
							FWJLNotifyRecordTMap.put("Status", 1);
							FWJLNotifyRecordTMap.put("IsRead", 0);
							FWJLNotifyRecordTMap.put("Flag", 0);
							FWJLNotifyRecordTMap.put("Creator", userId);
							FWJLNotifyRecordTMap.put("CreateTime", currentTime);
							notifyRecordTMapList.add(FWJLNotifyRecordTMap); //把区域服务经理消息推送记录添加到消息提醒表对象list中
						}
						//推送App提醒消息
						if (CollectionUtils.isNotEmpty(qyfwjls)) {
							noticeService.push(3, 1, Long.valueOf(workOrderId), qyfwjls.get(0).getId(),
									qyfwjls.get(0).getUserName(), "新工单提醒", JLtext, JLtext, userId);
						}
					}
				}
			}

			//保存消息提醒记录表数据
			if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
				workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
			}
			//插入并保存工单操作记录表数据
			Map<String, Object> workOrderFlowTMap = new HashMap<String, Object>(); //新建工单操作记录对象
			workOrderFlowTMap.put("OrderId", Long.parseLong(workOrderId));
			workOrderFlowTMap.put("ProcessorId", userId);
			workOrderFlowTMap.put("OrderStatus", 6); //工单状态为待派服务技师
			workOrderFlowTMap.put("ProcessComment", "");
			workOrderFlowTMap.put("ProLocLon", /*Float.parseFloat((String) map.get("LocLon"))*/MapUtils.getFloatValue(map,"LocLon",  0));
			workOrderFlowTMap.put("ProLocLat", /*Float.parseFloat((String) map.get("LocLat"))*/MapUtils.getFloatValue(map,"LocLat",  0));
			workOrderFlowTMap.put("ProLocation",  map.get("Location"));
			workOrderFlowTMap.put("IMEI",  map.get("IMEI")); //手机串号
			workOrderFlowTMap.put("Flag", 0);
			//workOrderFlowTMap.put("Creator",userId);
			workOrderFlowTMap.put("CreateTime", currentTime);
			workOrderRepairDao.saveOperation(workOrderFlowTMap); //插入并保存工单操作记录数据
			//服务站接受工单后工没有指派服务技师时单负责人就是服务站站长和服务站信息员
			//获取服务站站长信息
			List<UserT> zZUserTList = userTDao.getUserTByServiceStationId(map);
			//判断服务站站长集合是否为空
			if (CollectionUtils.isNotEmpty(zZUserTList)) {
				for (UserT zZUserT : zZUserTList) {
					//新建服务站站长工单负责人表对象(保存关于服务站接单后工单负责人信息数据)
					if (zZUserT != null) {
						Map<String, Object> zhuWorkOrderPrincipalTMap = new HashMap<String, Object>();
						zhuWorkOrderPrincipalTMap.put("OrderId", workOrderId);
						zhuWorkOrderPrincipalTMap.put("OrderStatus", 6); //工单状态为待派服务技师
						zhuWorkOrderPrincipalTMap.put("IsPrincipal", 1); //是主负责人
						zhuWorkOrderPrincipalTMap.put("PrincipalId", zZUserT.getId());
						zhuWorkOrderPrincipalTMap.put("Audited", 0);
						zhuWorkOrderPrincipalTMap.put("Flag", 0);
						zhuWorkOrderPrincipalTMap.put("ProcessorId", userId);
						zhuWorkOrderPrincipalTMap.put("CreateTime", currentTime);
						workOrderRepairDao.savePrincipal(zhuWorkOrderPrincipalTMap); //插入并保存工单负责人表数据
					}
				}
			}
			//获取服务站信息员信息
			List<UserT> xXYUserTList = userTDao.getMsgUserTByServiceStationId(map);
			//判断服务站信息员集合是否为空
			if (CollectionUtils.isNotEmpty(xXYUserTList)) {
				for (UserT xXYUserT : xXYUserTList) {
					//新建服务站信息员工单负责人表对象(保存关于服务站接单后工单负责人信息数据)
					if (xXYUserT != null) {
						Map<String, Object> zhuWorkOrderPrincipalTMap = new HashMap<String, Object>();
						zhuWorkOrderPrincipalTMap.put("OrderId", workOrderId);
						zhuWorkOrderPrincipalTMap.put("OrderStatus", 6); //工单状态为待派服务技师
						zhuWorkOrderPrincipalTMap.put("IsPrincipal", 1); //是主负责人
						zhuWorkOrderPrincipalTMap.put("PrincipalId", xXYUserT.getId());
						zhuWorkOrderPrincipalTMap.put("Audited", 0);
						zhuWorkOrderPrincipalTMap.put("Flag", 0);
						zhuWorkOrderPrincipalTMap.put("ProcessorId", userId);
						zhuWorkOrderPrincipalTMap.put("CreateTime", currentTime);
						workOrderRepairDao.savePrincipal(zhuWorkOrderPrincipalTMap); //插入并保存工单负责人表数据
					}
				}
			}
			//把接受工单的信息详情同步到CRM
			Map<String, Object> parameters = new HashMap<String, Object>();
			parameters.put("orderNo", workOrderT.getOrderNo());
			parameters.put("needGoOut", IsOutside);
			parameters.put("billStatus", 6);
			parameters.put("actionTime", currentTime);
			parameters.put("directorName", userT.getContact());
			parameters.put("directorPhone", userT.getPhone());
			parameters.put("phoneIMEI", MapUtils.getString(map, "IMEI", ""));
			parameters.put("positionLat", MapUtils.getFloatValue(map, "LocLat", 0));
			parameters.put("positionLon", MapUtils.getFloatValue(map, "LocLon", 0));
			parameters.put("location", MapUtils.getString(map, "Location", ""));
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
				parameters.put("CCSSComplainerOrderNo", workOrderT.getOrderNoCrm());
				parameters.put("CCSSOrderNo", workOrderT.getCCSSOrderNo());
				parameters.put("customerName", workOrderT.getCustomerName());
				parameters.put("customerPhone", workOrderT.getCustomerPhone());
				parameters.put("customerCompany", workOrderT.getCustomerCompanyName());
				parameters.put("faultDesc", workOrderT.getCustomerComplaint());
				parameters.put("stationNo", workOrderT.getServiceCarNo());
			}
			//启动子线程同步CRM状态
			new Thread(() -> {
				try {
					CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
							companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
							platformServiceDao, redisClientUtils, parameters,null);
					if (crmResponeEntity.getStatus() != 0) {
						log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
								+ crmResponeEntity.getMessage());
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
				}
			}).start();
			Map<String, Object> returnMap = new HashMap<>();
			returnMap.put("oldUpdateTime", currentTime);
			obj.put("data", returnMap);
			obj.put("status", 0);
			obj.put("msg", "接受工单成功");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	//服务站拒绝工单(除了dbu区域工程师指派服务站，服务站拒单，其余服务站拒单都走这个)
	@Transactional
	@Override
	public ModelAndView serviceStationRefuseWorkOrder(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			String workOrderId = String.valueOf(map.get("ID")); //接收工单id
			if ("".equals(workOrderId) || workOrderId == null) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			String refuseReasonStation = (String) map.get("RefuseReasonStation"); //接收工单id
			if ("".equals(refuseReasonStation) || refuseReasonStation == null) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务站拒绝工单原因不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTById(map);
			//ccec服务商拒单会生成新工单，这里先获取旧工单信息，下面使用
			Map<String, Object> oldWorkOrderMap = workOrderTDao.getOrderById(workOrderT.getId());
			if (workOrderT.getOrderStatus() == 5) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务商已拒单!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (workOrderT.getOrderStatus() == 6) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务商已接单!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (workOrderT.getOrderStatus() == 16) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单已被关闭!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			// String userADId =
			// AESTool.decryptString(request.getHeader("userid"));//解密userid
			// UserT userT = loginDao.getUserByid(userADId);
			UserT userT = UserThreadLocal.get();
			Long userId = userT.getId(); //获取登陆人主键id
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			//保存服务站拒绝工单对工单表做的相应的修改
			map.put("RefuseTimeStation", currentTime); //服务站拒绝工单时间
			map.put("OrderStatus", 5); //服务商已拒单
			map.put("Updator", userId);
			map.put("UpdateTime", currentTime);
			map.put("OldUpdateTime", (String) map.get("updateTime")); //前端传来的这条工单的修改时间
			int updateNum = workOrderTDao.updateServiceStationRefuseWorkOrder(map);
			if (updateNum == 0) { //工单状态没修改成功
				obj.put("status", SMSEnum.type21.getIndex());
				obj.put("msg", SMSEnum.type21.getName());
				obj.put("data", "");
				//返回客户
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			//保存工单操作记录表
			saveOperation(Long.parseLong(workOrderId), userId, 5, refuseReasonStation, (String) map.get("LocLon"),
					(String) map.get("LocLat"), (String) map.get("Location"), (String) map.get("IMEI"), 0, userId,
					currentTime);
			//把拒绝工单的信息详情同步到CRM
			Map<String, Object> parameters = new HashMap<>();
			parameters.put("orderNo", workOrderT.getOrderNo());
			parameters.put("CRMNo", workOrderT.getOrderNoCrm());
			parameters.put("billStatus", 5);
			parameters.put("actionTime", currentTime);
			parameters.put("directorName", userT.getContact());
			parameters.put("directorPhone", userT.getPhone());
			parameters.put("refuseReason", refuseReasonStation);
			parameters.put("phoneIMEI", MapUtils.getString(map, "IMEI", ""));
			parameters.put("positionLat", MapUtils.getFloatValue(map, "LocLat", 0));
			parameters.put("positionLon", MapUtils.getFloatValue(map, "LocLon", 0));
			parameters.put("location", MapUtils.getString(map, "Location", ""));
			CompanyT ccecChannelCompany = companyTDao.getCompanyInfoByCompanyNo("CCEC");
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
				parameters.put("CCSSComplainerOrderNo", workOrderT.getOrderNoCrm());
				parameters.put("CCSSOrderNo", workOrderT.getCCSSOrderNo());
				parameters.put("customerName", workOrderT.getCustomerName());
				parameters.put("customerPhone", workOrderT.getCustomerPhone());
				parameters.put("customerCompany", workOrderT.getCustomerCompanyName());
				parameters.put("faultDesc", workOrderT.getCustomerComplaint());
			}
			Map<String, Object> sSRepair = serviceStationDao.getStationNoAndNameByStationIdAndCompanyId(
					workOrderT.getServiceStationId(), workOrderT.getOrderChannel());
			if (org.apache.commons.collections.MapUtils.isNotEmpty(sSRepair)) {
				parameters.put("stationNo", sSRepair.get("BusinessNo"));
				parameters.put("stationName", sSRepair.get("StationName"));
			} else {
				parameters.put("stationNo", "");
				parameters.put("stationName", "");
			}
			try {
				CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
						companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
						platformServiceDao, redisClientUtils, parameters,null);
				if (crmResponeEntity.getStatus() != 0) {
					log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
							+ crmResponeEntity.getMessage());
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
			}
			//服务站拒单时，如果redis中有待服务商接单超时原因，就删除
			Integer code = OverTimeType.TYPE3.getCode();
			String redisKey = "overTimeWorkOrderTypeKey-" + workOrderId + "-" + code;
			if (redisClientUtils.exists(redisKey)) {
				redisClientUtils.delkey(redisKey);
			}

			List<Map<String, Object>> notifyRecordTMapList = new ArrayList<>();
			//ccec 服务站拒单    以上逻辑都有不变
			//下面补充逻辑是   推送短信app提醒给服务站对应的400    重新生成新工单    新旧工单绑定     新工单负责人是还是之前服务站的400  推送消息
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
				map.put("ServiceStationId", workOrderT.getServiceStationId());
				map.put("OrderChannel", workOrderT.getOrderChannel());
				List<Map<String, Object>> areaManagerMapList = new ArrayList<>();
				if (1==workOrderT.getIsTechSupport()) {
					areaManagerMapList  = workOrderRepairDao.getManager(map);
				}else {
					areaManagerMapList = workOrderRepairDao.getAreaManager(map);
				}

				Map<String, Object> stationMap = serviceStationDao
						.getServiceStationById(workOrderT.getServiceStationId());
				String msgbody = "您有新工单信息，工单号" + workOrderT.getOrderNo();
				if (StringUtils.isNotEmpty(workOrderT.getCCSSOrderNo())) {
					msgbody += "（FW号" + workOrderT.getCCSSOrderNo() + "），";
				}
				if (MapUtils.isNotEmpty(stationMap)) {
					msgbody += "(" + MapUtils.getString(stationMap, "StationName") + ")";
				}
				msgbody += "服务商拒单，此工单结束，请重新派工";
				if (CollectionUtils.isNotEmpty(areaManagerMapList)) {
					for (Map<String, Object> areaManagerMap : areaManagerMapList) {
						long receiverId = MapUtils.getLongValue(areaManagerMap, "ID");
						String receiverUserName = MapUtils.getString(areaManagerMap, "UserName");
						savePrincipal(workOrderT.getId(), 5, 1, receiverId, userT.getId(), currentTime);
						noticeService.push(2, 1, workOrderT.getId(), receiverId, receiverUserName, "新工单提醒", msgbody,
								msgbody, userT.getId());
						SmsUtils.sendMessage(userT.getPhone(), msgbody);
						notifyRecordTMapList.add(saveMsgOperation(workOrderT.getId(), 2, 1, receiverId, msgbody, 1,
								currentTime, "", userT.getId()));
					}
				}
				if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
					workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
					//清空保存消息推送的集合     因为下面也在调用，不清空的话会重复插入
					notifyRecordTMapList = new ArrayList<>();
				}
				oldWorkOrderMap.put("createUserId", userT.getId());
				String newOrderNo = ""; //生成的新工单编号
				if (MapUtils.isNotEmpty(oldWorkOrderMap)) {
					int newOrderStatus = 24;//24	待400审核	400回访/诊断中/继续服务/待更新
					//调用公用方法   创建新工单
					Map<String, Object> newWorkOrderMap = createNewWorkOrder(oldWorkOrderMap, newOrderStatus);
					if (MapUtils.isNotEmpty(newWorkOrderMap)) {
						long newWorkOrderId = MapUtils.getLongValue(newWorkOrderMap, "OrderId");
						// 旧工单关联新工单表id
						newWorkOrderMap.put("newOrderId", newWorkOrderId);
						newWorkOrderMap.put("RelOrderId", newWorkOrderId);
						newWorkOrderMap.put("oldOrderId", workOrderT.getId());
						crmServiceDao.updateRelOrderId(newWorkOrderMap);
						newOrderNo = MapUtils.getString(newWorkOrderMap, "OrderNo");
						//保存工单操作记录表
						saveOperation(newWorkOrderId, userId, newOrderStatus, "ccec服务站拒单后生成新工单，待400审核",
								MapUtils.getString(map, "LocLon"), MapUtils.getString(map, "LocLat"),
								MapUtils.getString(map, "Location"), MapUtils.getString(map, "IMEI"), 0, userId,
								currentTime);
						//推送短信和app消息
						String newMsgbody = "您有工单待审核，工单号" + newOrderNo + "，请尽快处理。";
						if (CollectionUtils.isNotEmpty(areaManagerMapList)) {
							for (Map<String, Object> areaManagerMap : areaManagerMapList) {
								long receiverId = MapUtils.getLongValue(areaManagerMap, "ID");
								String receiverUserName = MapUtils.getString(areaManagerMap, "UserName");
								//保存负责人
								savePrincipal(newWorkOrderId, newOrderStatus, 1, receiverId, userT.getId(),
										currentTime);
								//推送app提醒并入库
								noticeService.push(2, 1, newWorkOrderId, receiverId, receiverUserName, "新工单提醒",
										newMsgbody, newMsgbody, userT.getId());
								SmsUtils.sendMessage(userT.getPhone(), newMsgbody); //推送短信
								//放进集合中   下面入库
								notifyRecordTMapList.add(saveMsgOperation(newWorkOrderId, 2, 1, receiverId, newMsgbody,
										1, currentTime, "", userT.getId()));
							}
							if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
								workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
							}
						}

					}
				}
				//把新生成的工单状态同步到CRM
				Map<String, Object> parameters2 = new HashMap<>();
				parameters2.put("orderNo", newOrderNo);
				parameters2.put("billStatus", 24);
				parameters2.put("actionTime", currentTime);
				parameters2.put("directorName", userT.getContact());
				parameters2.put("directorPhone", userT.getPhone());
				parameters2.put("phoneIMEI", MapUtils.getString(map, "IMEI", ""));
				parameters2.put("positionLat", MapUtils.getFloatValue(map, "LocLat", 0));
				parameters2.put("positionLon", MapUtils.getFloatValue(map, "LocLon", 0));
				parameters2.put("location", MapUtils.getString(map, "Location", ""));
				if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
					parameters2.put("CCSSComplainerOrderNo", workOrderT.getOrderNoCrm());
					parameters2.put("CCSSOrderNo", "");
					parameters2.put("customerName", workOrderT.getCustomerName());
					parameters2.put("customerPhone", workOrderT.getCustomerPhone());
					parameters2.put("customerCompany", workOrderT.getCustomerCompanyName());
					parameters2.put("faultDesc", workOrderT.getCustomerComplaint());
				}
				parameters2.put("stationNo", "");
				parameters2.put("stationName", "");
				try {
					CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
							companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
							platformServiceDao, redisClientUtils, parameters2,null);
					if (crmResponeEntity.getStatus() != 0) {
						log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
								+ crmResponeEntity.getMessage());
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
				}

			}
			CompanyT cciChannelCompany = companyTDao.getCompanyInfoByCompanyNo("CCI");
			if (workOrderT.getOrderChannel() == cciChannelCompany.getId()){
				long DBEngineerUsersId = -1;

				Map<String, Object> operatorRelation = operatorRelationDao.getOperatorByOrderId(workOrderT.getId());
				if (MapUtils.isNotEmpty(operatorRelation)) {
					List<UserT> DBEngineerUsers = loginDao.getUserByPhone(operatorRelation.get("Phone").toString());
					if (CollectionUtils.isNotEmpty(DBEngineerUsers)) {
						 DBEngineerUsersId = DBEngineerUsers.get(0).getId();
					}
				}
				/**
				 * 拒单发动短信
				 */
				String orderNo = workOrderT.getOrderNo();
				String ESN = workOrderT.getESN();
				String customerComplaint = workOrderT.getCustomerComplaint();
				String location = workOrderT.getLocation();
				String OEName = workOrderT.getoEMName();
				String uploadTime = map.get("oldUpdateTime") == null ? "" : map.get("oldUpdateTime").toString();
				String stationName = sSRepair.get("StationName") == null ? "" : sSRepair.get("StationName").toString();
				String message = "400系统派工的服务工单:" + orderNo + ",ESN: " + ESN + ",客户抱怨: " + customerComplaint
						+ ",故障地点: " + location + ",主机厂: " + OEName + ",报修时间: " + uploadTime + "  已被经销商(" + stationName
						+ "）拒单(拒单原因:" + refuseReasonStation + ")，请关注后续服务安排。";
				String phone = operatorRelation.get("Phone") == null ? "13231988405"
						: operatorRelation.get("Phone").toString();
				SmsUtils.sendMessage(phone, message);

				notifyRecordTMapList.add(saveMsgOperation(workOrderT.getId(), 2, 1, DBEngineerUsersId, message, 1,
						currentTime, "", userT.getId()));

				if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
					workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
					//清空保存消息推送的集合     因为下面也在调用，不清空的话会重复插入
					notifyRecordTMapList.clear();
				}

			}
			obj.put("data", "");
			obj.put("status", 0);
			obj.put("msg", "拒绝工单成功");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * @param oldWorkOrderMap  根据旧工单id获取到的旧工单所有字段的信息
	 * @param newOrderStatus  新工单状态
	 */
	Map<String, Object> createNewWorkOrder(Map<String, Object> oldWorkOrderMap, int newOrderStatus) {
		Map<String, Object> newWorkOrderMap = new HashMap<>(); //新工单map
		newWorkOrderMap.putAll(oldWorkOrderMap); //把旧工单map信息放入新工单map信息中
		long createUserId = MapUtils.getLongValue(newWorkOrderMap, "createUserId");
		// 后台自动生成工单编号
		/**
		 * <p>
		 * 自动生成工单编号，由 redis 更改为 sqlServer
		 * </p>
		 */
		String OrderNo = OrderGenerateUtil.getWorkOrderNo();
		//String OrderNo = workOrderRepairServiceImpl.getOrderNo(newWorkOrderMap);
		newWorkOrderMap.put("OrderNo", OrderNo);
		newWorkOrderMap.put("CCSSOrderNo", "");
		newWorkOrderMap.put("ServiceStationId", 0);
		newWorkOrderMap.put("OrderStatus", newOrderStatus);
		//新工单绑定的新工单主键id
		newWorkOrderMap.put("RelOrderId", "");
		//新工单绑定的旧工单的主键id
		newWorkOrderMap.put("RelOrderIdOld", MapUtils.getLongValue(oldWorkOrderMap, "ID"));
		//工单生成时间
		//newWorkOrderMap.put("CreateTime", LocalTimeUtil.getRealCurrentTime());
		//工单创建人ID
		newWorkOrderMap.put("Creator", createUserId);
		// 工单更新人
		newWorkOrderMap.put("Updator", createUserId);
		// 工单更新时间（修改工单判断条件之一）
		newWorkOrderMap.put("UpdateTime", LocalTimeUtil.getRealCurrentTime());
		int saveresult = workOrderRepairDao.CreateWorkOrder(newWorkOrderMap);
		return newWorkOrderMap;
	}

	//开始维修和维修完成接口(两个合为一个)
	@Transactional
	@Override
	public ModelAndView startRepairToEndWorkOrder(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			String userADId = AESTool.decryptString(request.getHeader("userid"));//解密userid
			UserT userT = loginDao.getUserByid(userADId);
			long orderId = Long.parseLong((String) map.get("orderId")); //接收工单id
			Long userId = userT.getId();
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			int type = Integer.parseInt((String) map.get("type")); //类型(1代表开始维修   2代表维修完成)
			Map<String, Object> workOrderMap = new HashMap<String, Object>();
			workOrderMap.put("oldUpdateTime", (String) map.get("updateTime")); //获取旧修改时间
			String finishTime =MapUtils.getString(map,"finishTime"); //获取点击维修完成按钮时间
			Integer isFaultCode = MapUtils.getInteger(map, "isFaultCode");
			if (null != isFaultCode) {
				workOrderMap.put("isFaultCode", isFaultCode);
			}
			String FaultCode = MapUtils.getString(map, "FaultCode");
			if (org.apache.commons.lang3.StringUtils.isNotBlank(FaultCode)) {
				workOrderMap.put("FaultCode", FaultCode);
			}
			int orderStatus = 11; //默认已到达
			if (type == 1) { //开始维修
				orderStatus = 12; //维修中
			}
			if (type == 2) { //维修完成
				//通过服务工单id获取未完成的诊断工单数量
				Map<String, Object> notFinishWorkorder = workOrderTDao.getDRWorkOrderByWorkOrderId(orderId);
				if (MapUtils.isNotEmpty(notFinishWorkorder)) {
					obj.put("status", 3);
					obj.put("msg", "检测到有诊断工单未完成，请前去诊断!");
					JSONObject jsonObject = new JSONObject();
					jsonObject.put("drWorkOrderId", notFinishWorkorder.get("ID"));
					jsonObject.put("ESN", notFinishWorkorder.get("ESN"));
					jsonObject.put("SMN", notFinishWorkorder.get("SMN"));
					jsonObject.put("createTime", notFinishWorkorder.get("CreateTime"));
					jsonObject.put("orderNo", notFinishWorkorder.get("OrderNo"));
					obj.put("data", jsonObject);
					//返回客户
					ParameterTool.writeResponse(response, obj.toString());
					return null;
				} else {
					Map<String, Object> query = new HashMap<>(1);
					query.put("ID", MapUtils.getString(map, "orderId"));
					WorkOrderT workOrderT = workOrderTDao.getWorkOrderTById(query);
					String updateTime = workOrderT.getUpdateTime();
					Long durationMinutes = LocalTimeUtil.getDurationMinutes(updateTime, currentTime);
					int orderChannel = workOrderT.getOrderChannel(); //当前工单的服务渠道
					if (orderChannel == 3) { //目前DCEC有30分钟限制
						if (durationMinutes < 10L) {
							obj.put("status", 4);
							obj.put("msg", "您的维修时间不足10分钟，请稍等再试，谢谢！");
							ParameterTool.writeResponse(response, obj.toString());
							return null;
						}
					}
				}
				orderStatus = 13; //待用户评价
			}
			workOrderMap.put("OrderStatus", orderStatus); //维修中或者待用户评价
			workOrderMap.put("Updator", userId);
			workOrderMap.put("UpdateTime", currentTime);
			workOrderMap.put("ID", orderId);
			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTById(workOrderMap);
			int orderChannel = workOrderT.getOrderChannel(); //当前工单的服务渠道
			if (orderChannel == 1 && type == 2) { //服务渠道是DBU且调用的服务完成功能    没有后面的逻辑
				//DBU渠道服务完成需要调用关闭主动升级工单接口
				//1: 服务工单异常关闭
				//2: 服务工单已取消
				//3: 服务工单已完成
				if (workOrderT.getOrderChannel() == 1) {
					escalationService.disableEscalationByWorkOrderId(workOrderT.getId(), 3);
				}
			} else {
				//修改工单状态
				if (orderChannel == 4 && type == 1) { //XCEC点击开始诊断和维修时
					// 前端传来是否需要政策性支持和故障类型字段
					int isNeedPolicyTypeSupport = MapUtils.getIntValue(map, "isNeedPolicyTypeSupport", 1);// 是否需要政策性支持(0:是
																											// 1:否) 默认否
					int faultType = MapUtils.getIntValue(map, "faultType", 1);// 故障类型(1:一般故障 2:重大故障 3:后处理类故障)
					workOrderMap.put("isNeedPolicyTypeSupport", isNeedPolicyTypeSupport);
					workOrderMap.put("faultType", faultType);
				}
				if (orderChannel == 4 && type == 2) { //XCEC点击维修完成时
					// 前端传来故障处理方法及结果
					String faultDealMethodAndConclusion = MapUtils.getString(map, "faultDealMethodAndConclusion", "");
					workOrderMap.put("faultDealMethodAndConclusion", faultDealMethodAndConclusion);

				}

				String takeSteps = MapUtils.getString(map, "takeSteps", "");
				workOrderMap.put("takeSteps", takeSteps);
				int updateNum = workOrderTDao.saveWorkOrderByUserAPPAppraise(workOrderMap);
				if (updateNum == 0) { //工单状态没修改成功
					obj.put("status", SMSEnum.type21.getIndex());
					obj.put("msg", SMSEnum.type21.getName());
					ParameterTool.writeResponse(response, obj.toString());
					return null;
				}
				// 保存工单操作记录表
				if (StringUtils.isNotEmpty(finishTime)) {
					saveOperationByFinishTime(orderId, userId, orderStatus, "", (String) map.get("locLon"),
							(String) map.get("locLat"), (String) map.get("location"), (String) map.get("IMEI"), 0,
							userId, finishTime, currentTime);
				} else {
					saveOperation(orderId, userId, orderStatus, "", (String) map.get("locLon"),
							(String) map.get("locLat"), (String) map.get("location"), (String) map.get("IMEI"), 0,
							userId, currentTime);
				}

				String smstext = "";
				if (type == 1) { //开始维修
					smstext = "您的工单服务技师开始维修，工单号" + workOrderT.getOrderNo() + "，";
				}
				if (type == 2) { //维修完成
					smstext = "您的工单服务技师维修完成，工单号" + workOrderT.getOrderNo() + "，";
				}
				if(workOrderT.getOrderChannel() == 1){
					smstext = smstext + "属于\"" + workOrderT.getSellType() + "\"" + (org.apache.commons.lang3.StringUtils.isNotBlank(workOrderT.getServiceSubtype()) ? "-" + workOrderT.getServiceSubtype() : "") + "，";
				}
				smstext  = smstext + "请查看！";
                obj.put("msg", SMSEnum.type21.getName());
                obj.put("data", "");
                //返回客户
				//保存工单负责人信息表
				if (type == 1) { //开始维修  负责人是主副服务技师
					map.put("workOrderId", orderId);
					List<WorkOrderPrincipalT> workOrderPrincipalTs = workOrderPrincipalTDao
							.getWorkOrderPrincipalTListByOrderId(map);
					if (workOrderPrincipalTs.size() != 0) {
						for (WorkOrderPrincipalT workOrderPrincipalT : workOrderPrincipalTs) {
							savePrincipal(workOrderPrincipalT.getOrderId(), orderStatus,
									workOrderPrincipalT.getIsPrincipal(), workOrderPrincipalT.getUserId(), userId,
									currentTime);
						}
					}
				}
				if (type == 2) { //维修完成   负责人是用户
					savePrincipal(workOrderT.getId(), orderStatus, 1, workOrderT.getCustomerId(), userId, currentTime);
				}
				//保存消息提醒表
				List<Map<String, Object>> notifyRecordTMapList = new ArrayList<Map<String, Object>>();
				//根据服务站id和服务渠道id获取区域服务经理手机号
				map.put("ServiceStationID", workOrderT.getServiceStationId());
				map.put("CompanyID", workOrderT.getOrderChannel());
				Map<String, Object> qygcsMap = new HashMap<>();
				if (workOrderT.getOrderChannel() == 1) { //DBU需求，只给指定的区域工程师推送消息
					qygcsMap = positionUserTDao.getDBUAreaManager(workOrderT.getId());
				}
				List<PositionUserT> positionUserTList = new ArrayList<>();
				if (1==workOrderT.getIsTechSupport()) {
					positionUserTList = positionUserTDao.getManager(map);
				}else {
					positionUserTList = positionUserTDao
							.getPostUserTListByServiceStationIdCompanyId(map);
				}
				if (CollectionUtils.isNotEmpty(positionUserTList)) {
					for (PositionUserT positionUserT : positionUserTList) {
						//如果是dbu的工单，并且能获取出来区域工程师
						if (workOrderT.getOrderChannel() == 1 && MapUtils.isNotEmpty(qygcsMap)) {
							//拿dbu指定的区域工程师手机号和上面的区域工程师集合循环比较，比较到了则推送，其他渠道工单不走此逻辑
							if (!(MapUtils.getString(qygcsMap, "DBEngineerPhone", "")
									.equals(positionUserT.getUserPhone()))) {
								continue;
							}
						}
						/**
						 * 20210812 【短信通知】【XCEC】短信通知取消 取消以下短信发送： 1）区域经理 新工单提醒 实时发送：您有新工单信息，工单号XXX，请查看。
						 * 2）区域经理 新工单提醒（400指派给区域服务经理）实时发送：您有新工单信息，工单号XXX，请尽快处理。 3）区域经理 工单接受提醒
						 * 实时发送：您有工单被接受，工单号XXX，请查看。 4）区域经理 技师接单提醒 实时发送：您有工单被接单，工单号XXX，请查看。 5）区域经理
						 * 技师已出发提醒 实时发送：您的工单服务技师已出发，工单号XXX，请查看。 6）区域经理 技师开始维修提醒
						 * 实时发送：您的工单服务技师开始维修，工单号XXX，请查看。 - 当前，之前已完成 7）区域经理 工单取消提醒
						 * 实时发送：您有工单取消，工单号XXX，请查看。 8）区域经理 服务商关闭工单提醒 实时发送：您有工单被关闭，工单号XXX，请查看。
						 */
						List<UserT> qyfwjls = loginDao.getUserByPhone(positionUserT.getUserPhone());
						if (CollectionUtils.isNotEmpty(qyfwjls)) {
							noticeService.push(6, 1, workOrderT.getId(), qyfwjls.get(0).getId(),
									qyfwjls.get(0).getUserName(), "新工单提醒", smstext, smstext, userId);
						}
						// sprint18：新增以下短信发送：
						// 1）区域经理接收7小时预警提醒短信，①短信模板：7小时预警提醒：XX服务商，现有维修工单将超时，请尽快处理
						// ②发送机制：服务总时长大于等于7小时实时发送，服务总时长=技师完成维修时间-工单创建时间；
						// 2）区域经理接收重大故障提醒短信，①短信模板：重大故障提醒：XXX服务商，,发动机号XXX，现有重大故障工单，请尽快处理
						// ②发送机制：技师接单点开始维修选择故障级别，如果选择是重大故障提交后短信实时提醒。
						int faultType = MapUtils.getIntValue(map, "faultType", 1);// 故障类型(1:一般故障 2:重大故障 3:后处理类故障)
						if (faultType == 2) {
							ServiceStationT serviceStationT = serviceStationDao
									.getSSById(workOrderT.getServiceStationId());
							if (null != serviceStationT) {
								String format = String.format(xcecFaultTypeStr, serviceStationT.getStationname(),
										workOrderT.getESN());
								SmsUtils.sendMessage(qyfwjls.get(0).getPhone(), format); // 调用短信接口推送短信
								Map<String, Object> FWJLNotifyRecordTMap = new HashMap<String, Object>();
								FWJLNotifyRecordTMap.put("OrderId", workOrderT.getId());
								FWJLNotifyRecordTMap.put("Function", 26); //服务商响应工单提醒
								FWJLNotifyRecordTMap.put("Category", 1); //新工单提醒
								FWJLNotifyRecordTMap.put("ReceiverId", qyfwjls.get(0).getId());
								FWJLNotifyRecordTMap.put("ExceptionInfo", "");
								FWJLNotifyRecordTMap.put("Content", format);
								FWJLNotifyRecordTMap.put("SendType", 1); //短信方式
								FWJLNotifyRecordTMap.put("SendTime", currentTime);
								FWJLNotifyRecordTMap.put("Status", 1);
								FWJLNotifyRecordTMap.put("IsRead", 0);
								FWJLNotifyRecordTMap.put("Flag", 0);
								FWJLNotifyRecordTMap.put("Creator", userId);
								FWJLNotifyRecordTMap.put("CreateTime", currentTime);
								notifyRecordTMapList.add(FWJLNotifyRecordTMap);
							}
						}
					}
				}
				// 获取所有的站长
				List<UserT> ZZuserTList = userTDao
						.getStationMasterListByServiceStationId(workOrderT.getServiceStationId());
				if (CollectionUtils.isNotEmpty(ZZuserTList)) {
					for (UserT zzuserT : ZZuserTList) {
						noticeService.push(6, 1, workOrderT.getId(), zzuserT.getId(), zzuserT.getUserName(), "新工单提醒",
								smstext, smstext, userId);
					}
				}
				/*
				 * //获取所有的信息员 List<UserT> XXYUserTList =
				 * userTDao.getMsgUserTByServiceStationId(map); if
				 * (CollectionUtils.isNotEmpty(XXYUserTList)) { for (UserT xxyuserT :
				 * XXYUserTList) { noticeService.push(6, 1, workOrderT.getId(),
				 * xxyuserT.getId(), xxyuserT.getUserName(), "新工单提醒", smstext, smstext, userId);
				 * } }
				 */
				// 终端用户
				// 通过手机号获取user_T表主键id
				List<UserT> customers = loginDao.getUserByPhone(workOrderT.getCustomerPhone());
				if (CollectionUtils.isNotEmpty(customers)) {
					noticeService.push(6, 1, workOrderT.getId(), customers.get(0).getId(),
							customers.get(0).getUserName(), "新工单提醒", smstext, smstext, userId);
				}
				//保存消息提醒信息
				if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
					workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
				}
				//dbu的工单需要推送公众号消息   dbu微信公众号查看工单详情url
				if (workOrderT.getOrderChannel() == 1) {
					String dbuWechatWorkOrderInfoUrl = propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
					//拼公众号中查看详情的url
					String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, orderId);
					//推送微信公众号消息
					String firstData = "您有一条重要的工单状态信息";
					String keyWord1 = "编号：" + workOrderT.getOrderNo();
					String keyWord2 = "您的工单服务技师" + (type == 1 ? "开始维修，请查看。" : "维修完成，期待您的评价!");
					// String keyWord2 = "您的工单服务技师开始维修，请查看。";
					String keyWord3 = type == 1 ? Dictionaries.OrderStatus_12.getName()
							: Dictionaries.OrderStatus_13.getName();
					String keyWord4 = UserThreadLocal.get().getContact();
					String remark = "请点击详情查看工单内容";
					iOrderPushMessageService.sendOrderMessage(orderId, urlFormat, firstData, keyWord1, keyWord2,
							keyWord3, keyWord4, remark);
				}
				//dcec的工单需要推送公众号消息   dcec微信公众号查看工单详情url

				Integer orderSource;
				try {
					orderSource = workOrderT.getOrderSource();
					if (workOrderT.getOrderChannel() == 3 && orderSource == 6) {
						String dbuWechatWorkOrderInfoUrl = propertiesUtils
								.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
						// Map<String, Object> weChatUserRelationTMap =
						// weChatUserRelationTDao.getWeChatUserRelationTByUserPhone(us.get(0).getPhone());
						// if (MapUtils.isNotEmpty(weChatUserRelationTMap)) {
						// 拼公众号中查看详情的url
						String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, workOrderT.getId());
						//推送微信公众号消息
						String firstData = "您有一条重要的工单状态信息";
						String keyWord1 = "编号：" + workOrderT.getOrderNo();
						String keyWord2 = "您的工单服务技师" + (type == 1 ? "开始维修，请查看。" : "维修完成，期待您的评价!");
						String keyWord3 = type == 1 ? Dictionaries.OrderStatus_12.getName()
								: Dictionaries.OrderStatus_13.getName();
						String keyWord4 = UserThreadLocal.get().getContact();
						String remark = "请点击详情查看工单内容";
						iOrderPushMessageService.sendOrderMessage(orderId, urlFormat, firstData, keyWord1, keyWord2,
								keyWord3, keyWord4, remark);

					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				//把工单状态的信息同步到CRM
				Map<String, Object> parameters = new HashMap<String, Object>();
				parameters.put("orderNo", workOrderT.getOrderNo());
				parameters.put("billStatus", orderStatus);
				parameters.put("actionTime", currentTime);
				parameters.put("directorName", userT.getContact());
				parameters.put("directorPhone", userT.getPhone());
				parameters.put("measures", takeSteps);
                if (null != isFaultCode) {
                    parameters.put("isTrouble", isFaultCode == 1);//sprint 47  xcec  完成时 添加 故障码
                }
                if (org.apache.commons.lang3.StringUtils.isNotBlank(FaultCode)) {
                    parameters.put("troubleCode", FaultCode); //sprint 47
                }
				if (type == 2) { //维修完成
					//当服务工单状态为待用户评价时     把诊断工单id和诊断工单web页面地址传给页面
					Map<String, Object> drWorkOrder = workOrderTDao.getDRWorkOrderByOrderId(workOrderT.getId());
					if (MapUtils.isNotEmpty(drWorkOrder)) { //有诊断工单
						String secretKey = MapUtils.getString(drWorkOrder, "SecretKey");
						if (StringUtils.isEmpty(secretKey)) {
							secretKey = MapUtils.getString(drWorkOrder, "OrderNo");
						}
						parameters.put("drOrderNo", drWorkOrder.get("OrderNo"));
						String drDiagnoseReport = propertiesUtils.getPropertiesValue("drDiagnoseReport")
								+ secretKey;
						parameters.put("drDiagnoseReport", drDiagnoseReport);
						parameters.put("SMN", drWorkOrder.get("SMN"));
						if (workOrderT.getOrderChannel() == 3 || workOrderT.getOrderChannel() == 4) { // dcec 待用户评价的工单
																										// 调用crm时需要把执行过的工单编号传过去
							// 根据诊断工单id获取诊断工单所有故障码和症状信息
							List<Map<String, Object>> drFaultInfoList = workOrderTDao.getDRFaultInfoListByDRWorkOrderId(
									Long.parseLong(drWorkOrder.get("ID").toString()));
							//保存传给CRM执行过的方案信息
							List<Map<String, Object>> doneSolutionList = new ArrayList<>();
							if (CollectionUtils.isNotEmpty(drFaultInfoList)) {
								//根据DRFaultInfo_T主键id获取所有执行过的方案编号
								for (Map<String, Object> drFaultInfo : drFaultInfoList) {
									List<Map<String, Object>> workOrderSolutionList = workOrderTDao
											.getworkOrderSolutionByDRFaultInfoId(
													Long.parseLong(drFaultInfo.get("ID").toString()));
//									String doneSolutionNoStr = "";//执行过的方案编号，以英文逗号隔开
									StringBuilder doneSolutionNoBud = new StringBuilder();//执行过的方案编号，以英文逗号隔开
									if (CollectionUtils.isNotEmpty(workOrderSolutionList)) {
										Map<String, Object> doneSolution = new HashMap<>();
										if (drFaultInfo.get("GetSolutionType").toString().equals("0")) {//故障码
											doneSolution.put("faultInfo", drFaultInfo.get("FaultCode"));
										} else { //症状
											doneSolution.put("faultInfo", drFaultInfo.get("SymptomName"));
										}
										List<Map<String, Object>> innerDoneSolutionList = new ArrayList<>();
										Map<String, Object> doneSolutionInfo = null;
										for (Map<String, Object> workOrderSolution : workOrderSolutionList) {
											doneSolutionInfo = new HashMap<>();
											doneSolutionInfo.put("doneSolutionNoStr",
													MapUtils.getString(workOrderSolution, "SolutionID", ""));
											doneSolutionInfo.put("doneSolutionNoDes", doneSolutionNoBud);
											doneSolutionInfo.put("doneSolution",
													MapUtils.getString(workOrderSolution, "SolutionTitle", ""));
											if (doneSolutionNoBud.length() > 0) {
												doneSolutionNoBud.append(",");
											}
											doneSolutionNoBud.append(workOrderSolution.get("SolutionID").toString());
											innerDoneSolutionList.add(doneSolutionInfo);
										}

										doneSolution.put("doneSolutionList", innerDoneSolutionList);
										doneSolutionList.add(doneSolution);
									}
								}
							}
							parameters.put("doneSolutionList", doneSolutionList);
						}
					} else { //没有诊断工单    这两个字段传空字符串
						parameters.put("drOrderNo", "");
						parameters.put("drDiagnoseReport", "");
						parameters.put("doneSolutionList", new ArrayList<>());
					}
				}
				try {
					parameters.put("phoneIMEI", MapUtils.getString(map, "IMEI", ""));
					parameters.put("positionLat", MapUtils.getFloatValue(map, "locLat", 0));
					parameters.put("positionLon", MapUtils.getFloatValue(map, "locLon", 0));
					parameters.put("location", MapUtils.getString(map, "location", ""));
					if (orderChannel == 4 && type == 1) { //XCEC点击开始诊断和维修时
						// 前端传来是否需要政策性支持和故障类型字段
						int isNeedPolicyTypeSupport = MapUtils.getIntValue(map, "isNeedPolicyTypeSupport", 1);// 是否需要政策性支持(0:是
																												// 1:否)
																												// 默认否
						int faultType = MapUtils.getIntValue(map, "faultType", 1);// 故障类型(1:一般故障 2:重大故障 3:后处理类故障)
						// 我和crm接口文档是否政策性字段值刚好相反，这里转一下传给crm
						if (isNeedPolicyTypeSupport == 1) {
							parameters.put("isPolicySupport", 0);
						} else {
							parameters.put("isPolicySupport", 1);
						}
						//我和crm接口文档故障类型值定义不一样，这里转一下传给crm
						if (faultType == 1) {
							parameters.put("faultType", 0);
						} else if (faultType == 2) {
							parameters.put("faultType", 1);
						} else if (faultType == 3) {
							parameters.put("faultType", 2);
						}
					}
					if (orderChannel == 4 && type == 2) { //xcec点击维修完成
						// 前端传来故障处理方法及结果
						String faultDealMethodAndConclusion = MapUtils.getString(map, "faultDealMethodAndConclusion",
								"");
						parameters.put("faultDealMethodAndConclusion", faultDealMethodAndConclusion);
						//查询  服务经理同步外出审批图片给SF+联调  sprint 56
						parameters.put("approvalGoingOut", approvalGoingOutTService.getListByOrderIdReturnList(orderId));
					}
					if (orderChannel == 1 && type == 1) { //DBU选择智能诊断，并创建工单时调用该接口
						String clickStartRepairTime = redisClientUtils.get(RedisKeys.dbuStartRepairTime(orderId));
						if (StringUtils.isNotEmpty(clickStartRepairTime)) {
							parameters.put("actionTime", clickStartRepairTime);
						}
					}
					CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
							companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
							platformServiceDao, redisClientUtils, parameters,null);
					if (crmResponeEntity.getStatus() != 0) {
						log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
								+ crmResponeEntity.getMessage());
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
				}
			}
			obj.put("status", 0);
			obj.put("msg", "success");
			obj.put("data", "");
			//返回客户
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	@Override
	public ModelAndView getSMNByESN(Map<String, Object> map) {
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		String esn = MapUtils.getString(map, "ESN");
		Map<String, Object> returnMap = getSMNByESN(request, esn);
		JSONObject obj = new JSONObject(); //声明返给前端json对象
		try {
			obj.put("status", 0);
			obj.put("msg", "success");
			obj.put("data", returnMap);
			//返回客户
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	//根据ESN获取SMN
	private Map<String, Object> getSMNByESN(HttpServletRequest request, String ESN) {
		//先从本地数据库查   如果有返给前端   如果没有调用美国接口
		Map<String, Object> engineMsgMap = engineMsgDao.getSMNByESN(ESN);
		Map<String, Object> data = new HashMap<>();
		String SMN = "";
		if (null != engineMsgMap && engineMsgMap.size() > 0) { //如果本地数据库查出来数据，返给前端
			SMN = MapUtil.getMapValue(engineMsgMap, "SMN");
			data.put("ESN", ESN);
			data.put("SMN", SMN);
			data.put("make", MapUtil.getMapValue(engineMsgMap, "MakeName"));
			data.put("model", MapUtil.getMapValue(engineMsgMap, "ModelName"));
			data.put("type", MapUtil.getMapValue(engineMsgMap, "TypeName"));
			data.put("name", "");
			data.put("phone", "");
		} else { //如果数据库没有，调用晓闪的接口
			Map<String, Object> map = getSMNBySibel(request, ESN);
			Map<String, Object> dataMap = (Map<String, Object>) MapUtils.getMap(map, "data");
			SMN = MapUtils.getString(dataMap, "SMN", "");
			data.put("ESN", ESN);
			data.put("SMN", SMN);
			data.put("make", "");
			data.put("model", "");
			data.put("type", "");
			data.put("name", "");
			data.put("phone", "");
		}
		Map<String, Object> returnMap = new HashMap<>();
		if (StringUtils.isEmpty(SMN)) {
			returnMap.put("status", 1); //查询不到 ESN 信息；
			returnMap.put("msg", "当前发动机不存在诊断维修方案，无法使用诊断维修方案");
			returnMap.put("data", "");
			return returnMap;
		}
		int isValidate = 0; //初始化验证信息，默认0不通过
		//获取数据库中所有支持的机型清单
		List<Map<String, Object>> engineTypeList = engineTypeTDao.getSupportEngineTypeTList();
		for (Map<String, Object> engineType : engineTypeList) {
			if (SMN.equals(engineType.get("SMN").toString())) {
				isValidate = 1; //如果SMN在支持机型清单列表中，代表是支持的SMN
				break;
			}
		}
		for (Map<String, Object> engineType : engineTypeList) {
            String standard = MapUtils.getString(engineType, "standard");
            standard = standard.substring(0, standard.length() - 1); //末尾以逗号结尾   截取掉
            List<String> stringList = StringToool.getStringList(standard, ",");
            String standardNew = dictionariesTDao.getSSAuthDvaule(stringList);
            engineType.put("standard", standardNew);
        }
		if (isValidate == 0) { //验证不通过
			returnMap.put("status", 2);
			returnMap.put("msg", "当前发动机不存在诊断维修方案，无法使用诊断维修方案");
			returnMap.put("data", "");
		} else {
			returnMap.put("status", 0);
			returnMap.put("msg", "success");
			returnMap.put("data", data);
		}
		return returnMap;
	}

	//调用sibel接口   单独提出来
	public Map<String, Object> getSMNBySibel(HttpServletRequest request, String ESN) {
		try {
			Header userId = new BasicHeader("userid", request.getHeader("userid"));
			Header token = new BasicHeader("Authorization", request.getHeader("Authorization"));
			//获取配置文件中调用common项目  sibel接口
			String url = PropertiesUtil.getProperties("projectconfig.properties", "getSMNByESNFromSIEBELUrl");
			url = String.format(url, ESN).trim();
			String response = HttpUtils.get(url, new ResponseHandler<String>() {
				@Override
				public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
					if (response.getStatusLine().getStatusCode() == 200) {
						HttpEntity httpEntity = response.getEntity();
						return EntityUtils.toString(httpEntity);
					} else {
						log.error("异常，response：" + response);
					}
					return null;
				}
			}, userId, token);
			Map<String, Object> map = JsonUtils.toJavaObject(response, Map.class);
		} catch (Exception e){
			log.error(e.getMessage(), e);
		}
		return null;
	}

	//当服务技师点击开始维修按钮时调用这个接口
	@Override
	public ModelAndView checkServiceStationPower(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		net.sf.json.JSONObject obj = new net.sf.json.JSONObject(); //声明返给前端json对象
		String userADId = AESTool.decryptString(request.getHeader("userid"));//解密userid
		UserT userT = loginDao.getUserByid(userADId);
		long orderId = Long.parseLong((String) map.get("orderId")); //接收工单id
		// 判断是否有诊断工单在创建，或已完成智能诊断工单创建
		String key = "addOrder" + userT.getUserName();
		String value = redisClientUtils.get(key);
		if (StringUtils.isNotEmpty(value)){
			value = value.replaceAll("\"","");
			long time = LocalTimeUtil.getDurationMinutes(LocalTimeUtil.getRealCurrentTime(),value);
			if(time > 0 && time < 10){
				obj.put("status", -3);
				obj.put("msg", "该服务工单正在创建智能诊断中，请稍后再试！");
				ParameterTool.writeResponse(response, obj.toString());
			}
		}
		int count = workOrderDrDao.getDRWorkOrderByOrderId(orderId);
		if (count > 0){
			obj.put("status", -3);
			obj.put("msg", "该服务工单已完成智能诊断工单的创建！");
			ParameterTool.writeResponse(response, obj.toString());
		}
		Map<String, Object> workOrderMap = new HashMap<>();
		workOrderMap.put("ID", orderId);
		WorkOrderT workOrderT = workOrderTDao.getWorkOrderTById(workOrderMap);
		//移动技师可能不属于服务站    这块判断技师所属服务站是否有权限改为服务工单所属服务站是否有权限
		Map<String, Object> serviceStation = serviceStationDao.getServiceStationById(workOrderT.getServiceStationId());
		int drFunStatus = 0; //保存服务站是否有诊断维修的权限   默认值为0   没有权限
		if (null != serviceStation) {
			drFunStatus = Integer.parseInt(serviceStation.get("DRFunStatus").toString());
		}
		if (drFunStatus == 0) { //没有诊断维修的权限
			obj.put("status", 0);
			obj.put("msg", "");
			Map<String, Object> data = new HashMap<>();
			data.put("DRFunStatus", drFunStatus);
			obj.put("data", data);
			//返回客户
			ParameterTool.writeResponse(response, obj.toString());
		} else { //有诊断维修的权限
			String esn = workOrderT.getESN();
			Header userid = new BasicHeader("userid", request.getHeader("userid"));
			Header token = new BasicHeader("Authorization", request.getHeader("Authorization"));
			String url = PropertiesUtil.getProperties("projectconfig.properties", "getSMNByESNUrl");
			url = String.format(url, 0, esn);
			String responseData = HttpUtils.get(url, new ResponseHandler<String>() {
				@Override
				public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
					if (response.getStatusLine().getStatusCode() == 200) {
						HttpEntity httpEntity = response.getEntity();
						return EntityUtils.toString(httpEntity);
					} else {
						log.error("异常，response：" + response);
					}
					return null;
				}
			}, userid, token);
			Map<String, Object> enginerMsg = JsonUtils.toJavaObject(responseData, Map.class);
			//status不为0代表该ESN没有获取到SMN或者SMN不在支持清单中
			if (null != enginerMsg && MapUtils.getIntValue(enginerMsg, "status") == 0 && enginerMsg.containsKey("data")) {
				//status为0代表ESN在支持清单中  需要把诊断维修生成工单的相关数据返给前端
				Map<String, Object> data = (Map<String, Object>) enginerMsg.get("data");
				data.put("name", workOrderT.getCustomerName());
				data.put("phone", workOrderT.getCustomerPhone());
				data.put("DRFunStatus", drFunStatus);
				data.put("workOrderId", workOrderT.getId());
				data.put("customerComplaint", workOrderT.getCustomerComplaint());
			}
			JSONObject json = new JSONObject(enginerMsg);
			ParameterTool.writeResponse(response, json.toString());
		}

		return null;
	}

	//区域工程师远程解决服务工单功能(DBU)，DBU服务技师点击维修完成
	@Transactional
	@Override
	public ModelAndView areaEngineerLongResolve(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		String eAppVersion = request.getHeader("EAppVersion");
		//填报类型 1：自动保存 0：提交
		Integer type = MapUtils.getInteger(map,"type", 0);
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			if (!map.containsKey("OrderId")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			long orderId = Long.parseLong(map.get("OrderId").toString()); //服务工单id
			Integer userAction = MapUtils.getInteger(map,"UserAction");  //用户行为

			if(type == 0){
				if (!map.containsKey("ProblemLevel")) {
					obj.put("data", "");
					obj.put("status", 1);
					obj.put("msg", "问题等级不能为空!");
					ParameterTool.writeResponse(response, obj.toString());
					return null;
				}
				if (!map.containsKey("FaultSolution")) {
					obj.put("data", "");
					obj.put("status", 1);
					obj.put("msg", "故障解决方案不能为空!");
					ParameterTool.writeResponse(response, obj.toString());
					return null;
				}
				if (!map.containsKey("UserAction")) {
					obj.put("data", "");
					obj.put("status", 1);
					obj.put("msg", "用户行为不能为空!");
					ParameterTool.writeResponse(response, obj.toString());
					return null;
				}
				if (userAction == 1 || userAction == 2) {
					if (!map.containsKey("Reason")) {
						obj.put("data", "");
						obj.put("status", 1);
						obj.put("msg", "原因不能为空!");
						ParameterTool.writeResponse(response, obj.toString());
						return null;
					}
				}
				if (userAction == 3 || userAction == 4) {
					if (!map.containsKey("ComponentName") || !map.containsKey("ComponentNo")
							|| !map.containsKey("InvalidModel") || !map.containsKey("InvalidModelSum")) {
						obj.put("data", "");
						obj.put("status", 1);
						obj.put("msg", "零件名称，零件号，失效模式，失效模式描述不能为空!");
						ParameterTool.writeResponse(response, obj.toString());
						return null;
					}
				}
			}

			Integer problemLevel = MapUtils.getInteger(map,"ProblemLevel");//问题等级
			String faultSolution = MapUtils.getString(map,"FaultSolution"); //故障解决方案
			String oldUpdateTime = MapUtils.getString(map,"oldUpdateTime"); //工单之前的修改时间
			String locLon = /*(String) map.get("LocLon")*/MapUtils.getString(map,"LocLon","");
			String locLat = /*(String) map.get("LocLat")*/MapUtils.getString(map,"LocLat","");
			String location = /*(String) map.get("Location")*/MapUtils.getString(map,"Location","");
			String IMEI = /*(String) map.get("IMEI")*/MapUtils.getString(map,"IMEI","");
			//服务性质
			Integer serviceNature = MapUtils.getInteger(map,"ServiceNature");
			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(orderId); // 根据工单id获取工单
			/*
			 * String userId = AESTool.decryptString(request.getHeader("userid"));//解密userid
			 * UserT userT = loginDao.getUserByid("1");
			 */
			UserT userT = UserThreadLocal.get();
			long userId = userT.getId();
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			String phone = workOrderT.getCustomerPhone();
			List<UserT> customers = loginDao.getUserByPhone(phone);

			//保存诊断结论到数据库诊断结论表
			Map<String, Object> diagnoseConclusionMap = new HashMap<>();
			diagnoseConclusionMap.put("OrderId", orderId);
			diagnoseConclusionMap.put("ProblemLevel", problemLevel);
			diagnoseConclusionMap.put("FaultSolution", faultSolution);
			diagnoseConclusionMap.put("UserAction", userAction);
			if (userAction == 1 || userAction == 2) {
				diagnoseConclusionMap.put("Reason", map.get("Reason"));
			} else if (userAction == 3 || userAction == 4) {
				diagnoseConclusionMap.put("ComponentName", map.get("ComponentName"));
				diagnoseConclusionMap.put("ComponentNo", map.get("ComponentNo"));
				diagnoseConclusionMap.put("InvalidModel", map.get("InvalidModel"));
				diagnoseConclusionMap.put("InvalidModelSum", map.get("InvalidModelSum"));
			}
			diagnoseConclusionMap.put("Flag", 0);
			diagnoseConclusionMap.put("Creator", userId);
			diagnoseConclusionMap.put("CreateTime", currentTime);
			diagnoseConclusionMap.put("MultipleEnginesFlag", map.get("MultipleEnginesFlag"));
			//服务性质
			if(null != serviceNature){
				diagnoseConclusionMap.put("ServiceNature", serviceNature);
			}
			diagnoseConclusionTDao.deleteByOrderId(orderId, userId, currentTime);
			diagnoseConclusionTDao.insert(diagnoseConclusionMap);
			if(type == 0) {
				//获取工单修改前的状态
				int oldOrderStatus = workOrderT.getOrderStatus();
				//如果用户存在   工单状态为待用户评价    如果不存在   工单状态为服务完成
				int orderStatus = 13; //默认待用户评价
				if (CollectionUtils.isEmpty(customers)) {
					orderStatus = 14;//服务完成
				}

				//技师在诊断维修结论页面，满足以下条件需填写对应的24H超时原因，72H超时原因，提示
				String dbuResolve = appVersionTDao.getVersionCompatible("dbuResolve");
				String appVersion = StringUtils.isNotBlank(workOrderT.getAppVersion()) ? workOrderT.getAppVersion() : eAppVersion;
				String marketType = workOrderT.getMarketType();
				//市场分类：不等于bus 客车市场，或者不等于Truck卡车市场，或者不等于Construction 工程机械市场
				//故障等级=一般故障
				boolean success = StringUtils.isNotEmpty(marketType) && !marketType.equals("Bus 客车") && !marketType.equals("Truck 卡车") && !marketType.equals("Construction 工程机械");
				//诊断维修结论点击提交按钮的时间-工单创建时间
				Integer hours = (int) LocalTimeUtil.getDurationHours(workOrderT.getCreateTime(), currentTime);
				//是否填写24小时超时原因
				boolean isFill24 = false;
				//是否填写72小时超时原因
				boolean isFill72 = false;
				//rv超时原因
				List<WorkOrderReasonTimeoutRecordTVo> timeoutRecordTVoList = workOrderReasonTimeoutRecordTMapper.selectList(orderId);
				ObjectMapper objectMapper = new ObjectMapper();
				if (CollectionUtils.isNotEmpty(timeoutRecordTVoList)) {
					WorkOrderReasonTimeoutRecordTVo recordTVo = timeoutRecordTVoList.get(0);
					if (StringUtils.isNotBlank(recordTVo.getTimeoutDic())) {
						List<TimeoutDic> timeoutDicList = objectMapper.readValue(recordTVo.getTimeoutDic(), new TypeReference<List<TimeoutDic>>() {
						});
						for (TimeoutDic timeoutDic : timeoutDicList) {
							if (null != timeoutDic.getDInt() && timeoutDic.getDInt() == 3) {
								isFill24 = true;
							}
							if (null != timeoutDic.getDInt() && timeoutDic.getDInt() == 5) {
								isFill72 = true;
							}
						}
					}
				}
			/*
			 故障等级=一般故障的时候， 工单的RV时长（诊断维修结论点击提交按钮的时间-工单创建时间）>24小时不允许为空
			 故障等级不等于一般故障的时候，工单的RV时长（诊断维修结论点击提交按钮的时间-工单创建时间）>72小时不允许为空
			 */
				boolean success24 = null != problemLevel && problemLevel == 1 && hours >= 24 && !isFill24;
				boolean success72 = null != problemLevel && problemLevel != 1 && hours >= 72 && !isFill72;
				log.info("dbu提交诊断维修结论接口，超时原因判断;appVersion:" + appVersion + ";hours:" + hours + ";success:" + success + ";success24:" + success24 + ";success72:" + success72);
				if (workOrderT.getOrderChannel() == 1 && StringUtils.isNotBlank(appVersion) && StringUtils.isNotBlank(dbuResolve)
						&& dbuResolve.compareTo(appVersion) <= 0 && success) {
					if (success24) {
						obj.put("data", "");
						obj.put("status", -88);
						obj.put("msg", "您的工单已超24小时，请填写24小时超时原因!");
						ParameterTool.writeResponse(response, obj.toString());
						return null;
					}
					if (success72) {
						obj.put("data", "");
						obj.put("status", -88);
						obj.put("msg", "您的工单已超72小时，请填写72小时超时原因!");
						ParameterTool.writeResponse(response, obj.toString());
						return null;
					}
				}
				//修改工单状态
				map.put("OrderStatus", orderStatus); //服务完成
				map.put("Updator", userId);
				map.put("UpdateTime", currentTime);
				map.put("OldUpdateTime", oldUpdateTime); //前端传来的这条工单的修改时间
				map.put("OrderId", orderId);
				int updateNum = workOrderTDao.updateWorkOrderFinish(map); //修改条数
				if (updateNum == 0) { //工单状态没修改成功
					obj.put("status", SMSEnum.type21.getIndex());
					obj.put("msg", SMSEnum.type21.getName());
					obj.put("data", "");
					// 主动回滚事务
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					//返回客户
					ParameterTool.writeResponse(response, obj.toString());
					return null;
				}
				//保存工单操作记录表
				saveOperation(orderId, userT.getId(), orderStatus, "", locLon, locLat, location, IMEI, 0, userT.getId(),
						currentTime);
				//保存消息提醒记录表
				String msg = "您的工单服务技师维修完成，工单号" + workOrderT.getOrderNo() + "，";
				if (workOrderT.getOrderChannel() == 1) {
					msg = msg + "属于\"" + workOrderT.getSellType() + "\"" + (StringUtils.isNotBlank(workOrderT.getServiceSubtype()) ? "-" + workOrderT.getServiceSubtype() : "") + "，";
				}
				msg = msg + "请查看!";
				//如果是待区域工程师处理状态(18)，则只给用户推送短信和app提醒，
				//反之就是服务技师点击维修完成，需要给区域工程师，服务商站长，信息员和终端用户推送app提醒
				List<Map<String, Object>> notifyRecordTMapList = new ArrayList<>();
				if (oldOrderStatus == 18) {
					SmsUtils.sendMessage(phone, msg); //调用短信接口推送短信
					if (CollectionUtils.isNotEmpty(customers)) {
						noticeService.push(10, 5, workOrderT.getId(), customers.get(0).getId(),
								customers.get(0).getUserName(), "工单维修完成", msg, msg, userT.getId());
					}
				} else {
					//根据服务站id和服务渠道id获取区域服务经理手机号
					map.put("ServiceStationID", workOrderT.getServiceStationId());
					map.put("CompanyID", workOrderT.getOrderChannel());
					Map<String, Object> qygcsMap = new HashMap<>();
					if (workOrderT.getOrderChannel() == 1) { //DBU需求，只给指定的区域工程师推送消息
						qygcsMap = positionUserTDao.getDBUAreaManager(workOrderT.getId());
					}
					List<PositionUserT> positionUserTList = positionUserTDao
							.getPostUserTListByServiceStationIdCompanyId(map);
					if (CollectionUtils.isNotEmpty(positionUserTList)) {
						for (PositionUserT positionUserT : positionUserTList) {
							//如果是dbu的工单，并且能获取出来区域工程师
							if (workOrderT.getOrderChannel() == 1 && MapUtils.isNotEmpty(qygcsMap)) {
								//拿dbu指定的区域工程师手机号和上面的区域工程师集合循环比较，比较到了则推送，其他渠道工单不走此逻辑
								if (!(MapUtils.getString(qygcsMap, "DBEngineerPhone", "")
										.equals(positionUserT.getUserPhone()))) {
									continue;
								}
							}
							List<UserT> qyfwjls = loginDao.getUserByPhone(positionUserT.getUserPhone());
							if (CollectionUtils.isNotEmpty(qyfwjls)) {
								noticeService.push(6, 1, workOrderT.getId(), qyfwjls.get(0).getId(),
										qyfwjls.get(0).getUserName(), "新工单提醒", msg, msg, userT.getId());
							}
						}
					}
					// 获取所有的站长
					List<UserT> ZZuserTList = userTDao
							.getStationMasterListByServiceStationId(workOrderT.getServiceStationId());
					if (CollectionUtils.isNotEmpty(ZZuserTList)) {
						for (UserT zzuserT : ZZuserTList) {
							noticeService.push(6, 1, workOrderT.getId(), zzuserT.getId(), zzuserT.getUserName(), "新工单提醒",
									msg, msg, userT.getId());
						}
					}
					/*
					 * //获取所有的信息员 List<UserT> XXYUserTList =
					 * userTDao.getMsgUserTByServiceStationId(map); if
					 * (CollectionUtils.isNotEmpty(XXYUserTList)) { for (UserT xxyuserT :
					 * XXYUserTList) { noticeService.push(6, 1, workOrderT.getId(),
					 * xxyuserT.getId(), xxyuserT.getUserName(), "新工单提醒", msg, msg, userT.getId());
					 * } }
					 */
					// 终端用户
					// 通过手机号获取user_T表主键id
					// List<UserT> customers =
					// loginDao.getUserByPhone(workOrderT.getCustomerPhone());
					if (CollectionUtils.isNotEmpty(customers)) {
						noticeService.push(6, 1, workOrderT.getId(), customers.get(0).getId(),
								customers.get(0).getUserName(), "新工单提醒", msg, msg, userT.getId());
					}
					//保存消息提醒信息
					if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
						workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
					}
					//dbu的工单需要推送公众号消息   dbu微信公众号查看工单详情url
					if (workOrderT.getOrderChannel() == 1) {
						String dbuWechatWorkOrderInfoUrl = propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
						// Map<String, Object> weChatUserRelationTMap =
						// weChatUserRelationTDao.getWeChatUserRelationTByUserPhone(us.get(0).getPhone());
						// if (MapUtils.isNotEmpty(weChatUserRelationTMap)) {
						// 拼公众号中查看详情的url
						String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, orderId);
						//推送微信公众号消息
						String firstData = "您有一条重要的工单状态信息";
						String keyWord1 = "编号：" + workOrderT.getOrderNo();
						String keyWord2 = "您的工单服务技师维修完成，期待您的评价！";
						String keyWord3 = Dictionaries.OrderStatus_13.getName();
						String keyWord4 = UserThreadLocal.get().getContact();
						String remark = "请点击详情查看工单内容";
						iOrderPushMessageService.sendOrderMessage(orderId, urlFormat, firstData, keyWord1, keyWord2,
								keyWord3, keyWord4, remark);
						// }
					}
				}

				//dcec的工单需要推送公众号消息   dcec微信公众号查看工单详情url

				Integer orderSource;
				try {
					orderSource = workOrderT.getOrderSource();
					if (workOrderT.getOrderChannel() == 3 && orderSource == 6) {
						String dbuWechatWorkOrderInfoUrl = propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
						// Map<String, Object> weChatUserRelationTMap =
						// weChatUserRelationTDao.getWeChatUserRelationTByUserPhone(us.get(0).getPhone());
						// if (MapUtils.isNotEmpty(weChatUserRelationTMap)) {
						// 拼公众号中查看详情的url
						String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, orderId);
						//推送微信公众号消息
						String firstData = "您有一条重要的工单状态信息";
						String keyWord1 = "编号：" + workOrderT.getOrderNo();
						String keyWord2 = "您的工单服务技师维修完成，期待您的评价！";
						String keyWord3 = Dictionaries.OrderStatus_13.getName();
						String keyWord4 = UserThreadLocal.get().getContact();
						String remark = "请点击详情查看工单内容";
						//########################
						iOrderPushMessageService.sendOrderMessage(workOrderT.getId(), urlFormat, firstData, keyWord1,
								keyWord2, keyWord3, keyWord4, remark);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}

				//调用2.2.3 APP系统同步工单状态信息到CRM系统
				Map<String, Object> parameters = new HashMap<>();
				parameters.put("orderNo", workOrderT.getOrderNo());
				parameters.put("CRMNo", workOrderT.getOrderNoCrm());
				parameters.put("billStatus", orderStatus);
				parameters.put("stationNo", "");
				parameters.put("refuseReason", "");
				parameters.put("timeOutReason", "");
				parameters.put("lackOfPart", new ArrayList<>());
				parameters.put("actionTime", currentTime);
				parameters.put("directorName", userT.getContact());
				parameters.put("directorPhone", userT.getPhone());
				parameters.put("planMileage", "");
				parameters.put("travelMileage", "");
				parameters.put("serviceCar", "");
				parameters.put("positionLat", 0);
				parameters.put("positionLon", 0);
				String multipleEnginesFlag = org.apache.commons.collections4.MapUtils.getString(map, "MultipleEnginesFlag");
				if (StringUtils.isNotBlank(multipleEnginesFlag)) {
					parameters.put("MultipleEnginesFlag", "是".equals(multipleEnginesFlag) ? "true" : "false");
				} else {
					parameters.put("MultipleEnginesFlag", "");
				}
				//服务性质
				String serviceNatureStr = "";
				if (null != serviceNature) {
					serviceNatureStr = dictionariesTDao.getListByDTableNameAndDInt("serviceNature", String.valueOf(serviceNature));
					parameters.put("serviceType", serviceNatureStr);
				}
				//当服务工单状态为待用户评价时     把诊断工单id和诊断工单web页面地址传给页面
				Map<String, Object> drWorkOrder = workOrderTDao.getDRWorkOrderByOrderId(workOrderT.getId());
				if (MapUtils.isNotEmpty(drWorkOrder)) { //有诊断工单
					String secretKey = MapUtils.getString(drWorkOrder, "SecretKey");
					if (StringUtils.isEmpty(secretKey)) {
						secretKey = MapUtils.getString(drWorkOrder, "OrderNo");
					}
					parameters.put("drOrderNo", drWorkOrder.get("OrderNo"));
					String drDiagnoseReport = propertiesUtils.getPropertiesValue("drDiagnoseReport")
							+ secretKey;
					parameters.put("drDiagnoseReport", drDiagnoseReport);
				} else { //没有诊断工单    这两个字段传空字符串
					parameters.put("drOrderNo", "");
					parameters.put("drDiagnoseReport", "");
				}
				if (CollectionUtils.isNotEmpty(loginDao.getUserByPhone(phone))) {
					parameters.put("appAppraise", 1);
				} else {
					parameters.put("appAppraise", 0);
				}
				try {
					CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
							companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
							platformServiceDao, redisClientUtils, parameters, null);
					if (crmResponeEntity.getStatus() != 0) {
						log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
								+ crmResponeEntity.getMessage());
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
				}

				//调用2.2.7 APP系统同步诊断维修结论信息到CRM系统
				Map<String, Object> parameters2 = new HashMap<>();
				parameters2.put("orderNo", workOrderT.getOrderNo());
				parameters2.put("CRMOrderNo", workOrderT.getOrderNoCrm());
				parameters2.put("drSolutions", faultSolution);
				parameters2.put("proLevel", problemLevel);
				parameters2.put("reasonType", userAction);
				if (StringUtils.isNotBlank(serviceNatureStr)) {
					parameters2.put("serviceType", serviceNatureStr);
				}
				if (userAction == 1 || userAction == 2) {
					parameters2.put("failureModeDes", map.get("Reason"));
				}
				if (userAction == 3 || userAction == 4) {
					parameters2.put("partNumbers", map.get("ComponentNo"));
					parameters2.put("partNames", map.get("ComponentName"));
					parameters2.put("failureMode", map.get("InvalidModel"));
					parameters2.put("failureModeDes", map.get("InvalidModelSum"));
				}

				try {
					CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().drConclusion(
							companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(), parameters2,
							redisClientUtils);
					if (crmResponeEntity.getStatus() != 0) {
						log.error("同步诊断维修结论信息至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
								+ crmResponeEntity.getMessage());
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.error("同步诊断维修结论信息至CRM失败!错误信息:" + e.getMessage(), e);
				}

				//调用移动技师诊断维修接口
				if (workOrderT.getOrderChannel() == 1) {
					//10	已出发
					//11	已到达
					//12	维修中
					//维修完成就是点击当前接口的时间
					String departTime = MapUtils.getString(
							workOrderFlowTDao.getWorkOrderFlowByOrderIdAndStatus(workOrderT.getId(), 10), "CreateTime", "");
					String arriveTime = MapUtils.getString(
							workOrderFlowTDao.getWorkOrderFlowByOrderIdAndStatus(workOrderT.getId(), 11), "CreateTime", "");
					String repairStartTime = MapUtils.getString(
							workOrderFlowTDao.getWorkOrderFlowByOrderIdAndStatus(workOrderT.getId(), 12), "CreateTime", "");
					JSONObject jsonObject = new JSONObject();
					jsonObject.put("departTime", departTime);
					jsonObject.put("arriveTime", arriveTime);
					Map<String, Object> selfDiagnosticDetailMap = workOrderSelfDiagnosticTDao
							.getSelfDiagnosticDetail(workOrderT.getId());
					jsonObject.put("repairDescription", MapUtils.getString(selfDiagnosticDetailMap, "RepairDesc", ""));
					jsonObject.put("repairAttachments", workOrderPicsDao.getPicUrlByOrderId(orderId));
					jsonObject.put("repairStartTime", repairStartTime);
					jsonObject.put("repairEndTime", LocalTimeUtil.getRealCurrentTime());
					jsonObject.put("serviceWorkOrderId", workOrderT.getId());
					//调用公共方法   请求移动技师接口
					log.info("dbu提交诊断维修结论接口，调用移动技师诊断维修接口,传参为:" + jsonObject.toString());
					Map<String, Object> resultMap = sendPostRequest(request, "mtAppFinishServiceUrl",
							jsonObject.toString());
					if (MapUtils.isNotEmpty(resultMap)) {
						int status = MapUtils.getIntValue(resultMap, "status");
						if (status != 0) {
							//主动回滚事务
							TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
							log.error("dbu提交诊断维修结论接口，调用移动技师诊断维修接口失败：" + MapUtils.getString(resultMap, "msg", ""));
							obj.put("data", "");
							obj.put("status", status);
							obj.put("msg", MapUtils.getString(resultMap, "msg", ""));
							ParameterTool.writeResponse(response, obj.toString());
							return null;
						}
					}
				}
				//DBU渠道关闭工单需要调用关闭主动升级工单接口
				//1: 服务工单异常关闭
				//2: 服务工单已取消
				//3: 服务工单已完成
				if (workOrderT.getOrderChannel() == 1) {
					escalationService.disableEscalationByWorkOrderId(workOrderT.getId(), 3);
				}
			}
			obj.put("data", "");
			obj.put("status", 0);
			obj.put("msg", "success");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}

		return null;
	}

	/**
	 * 诊断结论详情
	 * @param orderId
	 * @return
	 */
	@Override
	public DiagnoseConclusionInfo getDiagnoseByOrderId(Long orderId) {
		DiagnoseConclusionInfo info = new DiagnoseConclusionInfo();
		DiagnoseConclusionInfo  conclusionInfo = diagnoseConclusionTDao.getConclusionByOrderId(orderId);
		Map<String, Object> selfDiagnosticDetailMap = workOrderSelfDiagnosticTDao.getSelfDiagnosticDetail(orderId);
		if(null != conclusionInfo){
			info = conclusionInfo;
		}
		if (selfDiagnosticDetailMap != null && !selfDiagnosticDetailMap.isEmpty()) {
			info.setReplaceComponent(MapUtils.getInteger(selfDiagnosticDetailMap,"ReplacePart",0));
			info.setReplacecomponentName(MapUtils.getString(selfDiagnosticDetailMap,"ComponentName",""));
		}else {
			info.setReplaceComponent(0);
			info.setReplacecomponentName("");
		}
		return info;
	}

	Map<String, Object> sendPostRequest(HttpServletRequest request, String keyword, String jsonStr) {
		Header userId = new BasicHeader("userid", request.getHeader("userid"));
		Header token = new BasicHeader("Authorization", request.getHeader("Authorization"));
		String url = PropertiesUtil.getProperties("projectconfig.properties", keyword);
		String response = HttpUtils.postJson(url, jsonStr, new ResponseHandler<String>() {
			@Override
			public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
				if (response.getStatusLine().getStatusCode() == 200) {
					HttpEntity httpEntity = response.getEntity();
					return EntityUtils.toString(httpEntity);
				} else {
					log.error("异常，response：" + response);
				}
				return null;
			}
		}, userId, token);
		Map<String, Object> map = JsonUtils.toJavaObject(response, Map.class);
		return map;
	}

	//区域工程师指派服务工单给服务站(DBU)
	@Transactional
	@Override
	public ModelAndView areaEngineerAssignServerStation(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			if (!map.containsKey("OrderId")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (!map.containsKey("ServiceStationId")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务站id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (!map.containsKey("GuessDistance")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "预计里程不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			long orderId = Long.parseLong(map.get("OrderId").toString()); //服务工单id
			long serviceStationId = Long.parseLong(map.get("ServiceStationId").toString()); //服务站id
			Float guessDistance = Float.parseFloat(map.get("GuessDistance").toString());
			String oldUpdateTime = (String) map.get("oldUpdateTime"); //工单之前的修改时间
			String locLon = /*(String) map.get("LocLon")*/MapUtils.getString(map,"LocLon","");
			String locLat = /*(String) map.get("LocLat")*/MapUtils.getString(map,"LocLat","");
			String location = /*(String) map.get("Location")*/MapUtils.getString(map,"Location","");
			String IMEI = /*(String) map.get("IMEI")*/MapUtils.getString(map,"IMEI","");
			String userId = AESTool.decryptString(request.getHeader("userid"));//解密userid
			UserT userT = loginDao.getUserByid(userId);
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			Map<String, Object> updateWorkOrderAssignServerStationMap = new HashMap<>();
			updateWorkOrderAssignServerStationMap.put("ServiceStationId", serviceStationId);
			updateWorkOrderAssignServerStationMap.put("GuessDistance", guessDistance);
			updateWorkOrderAssignServerStationMap.put("UpdateTime", currentTime);
			updateWorkOrderAssignServerStationMap.put("Updator", userId);
			updateWorkOrderAssignServerStationMap.put("orderId", orderId);
			updateWorkOrderAssignServerStationMap.put("oldUpdateTime", oldUpdateTime);
			int updateNum = workOrderTDao.updateWorkOrderAssignServerStation(updateWorkOrderAssignServerStationMap);//修改工单信息
			if (updateNum == 0) { //工单状态没修改成功
				obj.put("status", SMSEnum.type21.getIndex());
				obj.put("msg", SMSEnum.type21.getName());
				obj.put("data", "");
				//返回客户
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}

			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(orderId); //根据工单id获取工单
			int orderStatus = 4;//待服务商接单

			//保存工单操作记录表
			saveOperation(orderId, userT.getId(), orderStatus, "区域工程师指派服务站", locLon, locLat, location, IMEI, 0,
					userT.getId(), currentTime);
			//保存消息提醒记录表
			//保存工单负责人表
			map.put("ServiceStationID", serviceStationId);
			List<UserT> zZUserTList = userTDao.getUserTByServiceStationId(map);
			//判断服务站站长集合是否为空
			if (CollectionUtils.isNotEmpty(zZUserTList)) {
				for (UserT zZUserT : zZUserTList) {
					//新建服务站站长工单负责人表对象(保存关于服务站接单后工单负责人信息数据)
					if (zZUserT != null) {
						//SmsTool.sendSms(zZUserT.getPhone(), msg);  //调用短信接口推送短信
						String newMsg = dbuMessageService.sendAssignMessage(zZUserT, workOrderT);
						List<Map<String, Object>> notifyRecordTMapList = new ArrayList<>();
						notifyRecordTMapList.add(saveMsgOperation(workOrderT.getId(), 2, 1, zZUserT.getId(), newMsg, 1,
								currentTime, "", userT.getId()));
						if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
							workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
						}

						// 发送推送
						noticeService.push(2, 1, orderId, zZUserT.getId(), zZUserT.getUserName(), "新工单提醒", newMsg, newMsg,
								userT.getId());

						Map<String, Object> zhuWorkOrderPrincipalTMap = new HashMap<String, Object>();
						zhuWorkOrderPrincipalTMap.put("OrderId", orderId);
						zhuWorkOrderPrincipalTMap.put("OrderStatus", 4); //工单状态为待服务商接单
						zhuWorkOrderPrincipalTMap.put("IsPrincipal", 1); //是主负责人
						zhuWorkOrderPrincipalTMap.put("PrincipalId", zZUserT.getId());
						zhuWorkOrderPrincipalTMap.put("Audited", 0);
						zhuWorkOrderPrincipalTMap.put("Flag", 0);
						zhuWorkOrderPrincipalTMap.put("ProcessorId", userId);
						zhuWorkOrderPrincipalTMap.put("CreateTime", currentTime);
						workOrderRepairDao.savePrincipal(zhuWorkOrderPrincipalTMap); //插入并保存工单负责人表数据
					}
				}
			}
			//获取服务站信息员信息
			List<UserT> xXYUserTList = userTDao.getMsgUserTByServiceStationId(map);
			//判断服务站信息员集合是否为空
			if (CollectionUtils.isNotEmpty(xXYUserTList)) {
				for (UserT xXYUserT : xXYUserTList) {
					//新建服务站信息员工单负责人表对象(保存关于服务站接单后工单负责人信息数据)
					if (xXYUserT != null) {
						String newMsg = dbuMessageService.sendAssignMessage(xXYUserT, workOrderT);
						//SmsTool.sendSms(xXYUserT.getPhone(), msg);  //调用短信接口推送短信
						// APP推送
						noticeService.push(2, 1, orderId, xXYUserT.getId(), xXYUserT.getUserName(), "新工单提醒", newMsg, newMsg,
								userT.getId());
						List<Map<String, Object>> notifyRecordTMapList = new ArrayList<>();
						notifyRecordTMapList.add(saveMsgOperation(workOrderT.getId(), 2, 1, xXYUserT.getId(), newMsg, 1,
								currentTime, "", userT.getId()));
						if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
							workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
						}

						Map<String, Object> zhuWorkOrderPrincipalTMap = new HashMap<String, Object>();
						zhuWorkOrderPrincipalTMap.put("OrderId", orderId);
						zhuWorkOrderPrincipalTMap.put("OrderStatus", 4); //工单状态为待服务商接单
						zhuWorkOrderPrincipalTMap.put("IsPrincipal", 1); //是主负责人
						zhuWorkOrderPrincipalTMap.put("PrincipalId", xXYUserT.getId());
						zhuWorkOrderPrincipalTMap.put("Audited", 0);
						zhuWorkOrderPrincipalTMap.put("Flag", 0);
						zhuWorkOrderPrincipalTMap.put("ProcessorId", userId);
						zhuWorkOrderPrincipalTMap.put("CreateTime", currentTime);
						workOrderRepairDao.savePrincipal(zhuWorkOrderPrincipalTMap); //插入并保存工单负责人表数据
					}
				}
			}
			//调用2.2.3 APP系统同步工单状态信息到CRM系统
			Map<String, Object> parameters = new HashMap<>();
			parameters.put("orderNo", workOrderT.getOrderNo());
			parameters.put("CRMNo", workOrderT.getOrderNoCrm());
			parameters.put("billStatus", orderStatus);
			Map<String, Object> sSRepair = serviceStationDao.getSSRepairByStationIdAndCompanyId(serviceStationId,
					workOrderT.getOrderChannel());
			if (MapUtils.isNotEmpty(sSRepair)) {
				parameters.put("stationNo", sSRepair.get("BusinessNo"));
			} else {
				parameters.put("stationNo", "");
			}
			parameters.put("refuseReason", "");
			parameters.put("timeOutReason", "");
			parameters.put("lackOfPart", new ArrayList<>());
			parameters.put("actionTime", currentTime);
			parameters.put("directorName", userT.getContact());
			parameters.put("directorPhone", userT.getPhone());
			parameters.put("planMileage", "");
			parameters.put("travelMileage", "");
			parameters.put("serviceCar", "");
			parameters.put("positionLat", 0);
			parameters.put("positionLon", 0);
			parameters.put("drOrderNo", "");
			parameters.put("drDiagnoseReport", "");
			try {
				CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
						companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
						platformServiceDao, redisClientUtils, parameters,null);
				if (crmResponeEntity.getStatus() != 0) {
					log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
							+ crmResponeEntity.getMessage());
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
			}

			obj.put("data", "");
			obj.put("status", 0);
			obj.put("msg", "success");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}

		return null;
	}

	//服务站拒绝工单(区域工程师指派服务站，服务站拒单调用这个方法)(DBU)
	@Transactional
	@Override
	public ModelAndView serviceStationRefuseWorkOrderForDBU(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			if (!map.containsKey("OrderId")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (!map.containsKey("RefuseReasonStation")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务站拒绝工单原因不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			long orderId = Long.parseLong(map.get("OrderId").toString());
			//判断这条工单有没有待区域工程师处理的状态    有 走后面的逻辑   没有调用DCEC服务站拒单的逻辑
			if (workOrderTDao.isHaveEighteenOrderStutas(orderId) == 0) {
				map.put("ID", orderId);
				map.put("updateTime", map.get("oldUpdateTime"));
				return serviceStationRefuseWorkOrder(map);
			}
			String refuseReasonStation = map.get("RefuseReasonStation").toString();
			String userId = AESTool.decryptString(request.getHeader("userid"));//解密userid
			UserT userT = loginDao.getUserByid(userId);
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			//保存服务站拒绝工单对工单表做的相应的修改
			map.put("ID", orderId);
			map.put("RefuseTimeStation", currentTime); //服务站拒绝工单时间
			map.put("RefuseReasonStation", refuseReasonStation); //服务站拒绝工单原因
			map.put("OrderStatus", 5); //服务商已拒单
			map.put("Updator", userId);
			map.put("UpdateTime", currentTime);
			map.put("OldUpdateTime", map.get("oldUpdateTime")); //前端传来的这条工单的上一次修改时间
			int updateNum = workOrderTDao.updateServiceStationRefuseWorkOrder(map);
			if (updateNum == 0) { //工单状态没修改成功
				obj.put("status", SMSEnum.type21.getIndex());
				obj.put("msg", SMSEnum.type21.getName());
				obj.put("data", "");
				//返回客户
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			Map<String, Object> workOrderT = workOrderTDao.getOrderById(orderId);
			//保存工单操作记录表
			saveOperation(orderId, userT.getId(), 5, refuseReasonStation, (String) map.get("LocLon"),
					(String) map.get("LocLat"), (String) map.get("Location"), (String) map.get("IMEI"), 0,
					userT.getId(), currentTime);
			//调用2.2.3 APP系统同步工单状态信息到CRM系统
			//后台自动生成工单编号
			/**
			 * <p>
			 *     自动生成工单编号，由 redis 更改为 sqlServer
			 * </p>
			 */
			String OrderNo = OrderGenerateUtil.getWorkOrderNo();
			//String OrderNo = workOrderRepairService.getOrderNo(map);
			map.put("ServiceStationID", workOrderT.get("ServiceStationId"));
			map.put("CompanyID", 1);
			List<Map<String, Object>> ssRepairTList = sSRepairTDao.getSSRepairTByServiceStationIDCompanyID(map);
			Map<String, Object> parameters = new HashMap<>();
			parameters.put("orderNo", workOrderT.get("OrderNo"));
			parameters.put("CRMNo", workOrderT.get("OrderNoCrm"));
			if (CollectionUtils.isNotEmpty(ssRepairTList)) {
				parameters.put("stationNo", ssRepairTList.get(0).get("BusinessNo"));
			}
			parameters.put("billStatus", 5);
			parameters.put("newOrderNo", OrderNo);
			parameters.put("refuseReason", refuseReasonStation);
			parameters.put("timeOutReason", "");
			parameters.put("lackOfParts", new ArrayList<>());
			parameters.put("actionTime", currentTime);
			parameters.put("directorName", userT.getContact());
			parameters.put("directorPhone", userT.getPhone());
			parameters.put("planMileage", "");
			parameters.put("travelMileage", "");
			parameters.put("serviceCar", "");
			parameters.put("positionLat", 0);
			parameters.put("positionLon", 0);
			parameters.put("drOrderNo", "");
			parameters.put("drDiagnoseReport", "");
			try {
				CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi()
						.syncOrderStatusToCrm(companyTDao
								.getCompanyInfoByCompanyID(Long.parseLong(workOrderT.get("OrderChannel").toString()))
								.getCompanyNo(), platformServiceDao, redisClientUtils, parameters,null);
				if (crmResponeEntity.getStatus() != 0) {
					log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
							+ crmResponeEntity.getMessage());
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
			}

			//因为是区域工程师指派服务站   服务站拒单    需要生成新工单   推送消息和指定负责人
			//新工单绑定旧工单id
			int orderStatus = 18;
			workOrderT.put("OrderNo", OrderNo);
			workOrderT.put("RelOrderIdOld", orderId);
			workOrderT.put("OrderStatus", orderStatus);
			workOrderT.put("ServiceStationId", -1);
			workOrderRepairDao.CreateWorkOrder(workOrderT); //生成新工单

			//新工单主键id
			long newOrderId = Long.parseLong(workOrderT.get("OrderId").toString());
			//旧工单绑定新工单id
			Map<String, Object> newOrderMap = new HashMap<>();
			newOrderMap.put("newOrderId", newOrderId);
			newOrderMap.put("oldOrderId", orderId);
			confirmationByServiceManagerDao.updateRelOrderId(newOrderMap);

			//保存RecommendThreeStationForDBU_T表数据
			Map<String, Object> recommendThreeStationForDBUMap = allServiceStationDao
					.getRecommendThreeStationForDBUByOrderId(orderId);
			if (MapUtils.isNotEmpty(recommendThreeStationForDBUMap)) {
				recommendThreeStationForDBUMap.put("OrderId", newOrderId);
				crmPlatformServiceDao.saveRecommendThreeStationToTable(recommendThreeStationForDBUMap);
			}
			/*String locLon = (String) map.get("LocLon");
			String locLat = (String) map.get("LocLat");
			String location = (String) map.get("Location");
			String IMEI = (String) map.get("IMEI");*/
			String locLon = MapUtils.getString(map,"LocLon","");
			String locLat = MapUtils.getString(map,"LocLat","");
			String location = MapUtils.getString(map,"Location","");
			String IMEI = MapUtils.getString(map,"IMEI","");
			//保存工单操作记录表
			saveOperation(newOrderId, userT.getId(), orderStatus, "服务站拒单，重新生成工单", locLon, locLat, location, IMEI, 0,
					userT.getId(), currentTime);
			//保存消息提醒记录表
			String serviceSubtype = MapUtils.getString(workOrderT, "ServiceSubtype", "");
			String sellType = MapUtils.getString(workOrderT, "SellType", "");
			int OrderChannel = MapUtils.getIntValue(workOrderT, "OrderChannel");
			String msg = "您有新工单信息，工单号 " + OrderNo + "，";
			if(OrderChannel == 1){
				msg = msg + "属于\"" + sellType + "\"" + (org.apache.commons.lang3.StringUtils.isNotBlank(serviceSubtype) ? "-" + serviceSubtype : "") + "，";
			}
			msg = msg + "请尽快处理！";
			//根据旧工单id获取CAC审核通过工单后同步的服务站相关数据    保存新工单CAC推荐的三家服务站数据
			Map<String, Object> recommendThreeStationMap = allServiceStationDao
					.getRecommendThreeStationForDBUByOrderId(orderId);
			String userPhone = "";
			if (org.apache.commons.collections4.MapUtils.isNotEmpty(recommendThreeStationMap)) {
				userPhone = recommendThreeStationMap.get("DBEngineerPhone").toString();
			}
			List<UserT> userTS = loginDao.getUserByPhone(userPhone);
			SmsUtils.sendMessage(userPhone, msg); //调用短信接口推送短信
			//保存工单负责人表
			if (CollectionUtils.isNotEmpty(userTS)) {
				noticeService.push(2, 1, newOrderId, userTS.get(0).getId(), userTS.get(0).getUserName(), "新工单提醒", msg,
						msg, userT.getId());

				List<Map<String, Object>> notifyRecordTMapList = new ArrayList<>();
				notifyRecordTMapList.add(saveMsgOperation(newOrderId, 2, 1, userTS.get(0).getId(), msg, 1, currentTime,
						"", userT.getId()));
				if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
					workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
				}

				Map<String, Object> zhuWorkOrderPrincipalTMap = new HashMap<String, Object>();
				zhuWorkOrderPrincipalTMap.put("OrderId", newOrderId);
				zhuWorkOrderPrincipalTMap.put("OrderStatus", orderStatus); //工单状态为待区域工程师处理
				zhuWorkOrderPrincipalTMap.put("IsPrincipal", 1); //是主负责人
				zhuWorkOrderPrincipalTMap.put("PrincipalId", userTS.get(0).getId());
				zhuWorkOrderPrincipalTMap.put("Audited", 0);
				zhuWorkOrderPrincipalTMap.put("Flag", 0);
				zhuWorkOrderPrincipalTMap.put("ProcessorId", userId);
				zhuWorkOrderPrincipalTMap.put("CreateTime", currentTime);
				workOrderRepairDao.savePrincipal(zhuWorkOrderPrincipalTMap); //插入并保存工单负责人表数据
			} else {
				noticeService.push(2, 1, newOrderId, null, null, "新工单提醒", msg, msg, userT.getId());
			}

			// 保存到WorkOrderOperatorRelationDao
			Map<String, Object> operatorRelation = operatorRelationDao.getOperatorByOrderId(orderId);
			if (MapUtils.isNotEmpty(operatorRelation)) {
				Map<String, Object> operatorRelationMap = new HashMap<>();
				operatorRelationMap.put("OrderId", newOrderId);
				operatorRelationMap.put("OrderStatus", operatorRelation.get("OrderStatus"));
				operatorRelationMap.put("Name", operatorRelation.get("Name"));
				operatorRelationMap.put("Phone", operatorRelation.get("Phone"));
				operatorRelationMap.put("Creator", userId);
				operatorRelationMap.put("CreateTime", currentTime);
				//将新工单的CrmPositionName  补充
				operatorRelationMap.put("CrmPositionName", operatorRelation.get("CrmPositionName"));
				List<UserT> DBEngineerUsers = loginDao.getUserByPhone(operatorRelation.get("Phone").toString());
				if (CollectionUtils.isNotEmpty(DBEngineerUsers)) {
					long DBEngineerUsersId = DBEngineerUsers.get(0).getId();
					operatorRelationMap.put("UserId", DBEngineerUsersId);
				}
				operatorRelationMap.put("Flag", 0);
				operatorRelationDao.insertOperatorRelationInfo(operatorRelationMap);
			}
			obj.put("data", "");
			obj.put("status", 0);
			obj.put("msg", "success");
			Integer code = OverTimeType.TYPE3.getCode();
			String redisKey = "overTimeWorkOrderTypeKey-" + orderId + "-" + code;
			if (redisClientUtils.exists(redisKey)) {
				redisClientUtils.delkey(redisKey);
			}
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	//服务技师自行诊断服务工单(DBU)
	@Transactional
	@Override
	public ModelAndView selfDiagnosticWorkOrder(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			if (!map.containsKey("orderId")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			long orderId = Long.parseLong(map.get("orderId").toString());
			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(orderId);
			String diagnosticInfo = MapUtil.getMapValue(map, "diagnosticInfo");// 诊断过程描述
			String inspectInfo = MapUtil.getMapValue(map, "inspectInfo");// 检查测量记录
			String repairInfo = MapUtil.getMapValue(map, "repairInfo");// 维修过程描述
			int replaceComponent = Integer.parseInt(map.get("replaceComponent").toString());// 更换零部件0：否；1：是
			String component = MapUtil.getMapValue(map, "component");// 更换配件信息
			int isWorked = Integer.parseInt(map.get("isWorked").toString());// 是否有效0：否；1：是
			/*
			 * String userId = AESTool.decryptString(request.getHeader("userid"));//解密userid
			 * UserT userT = loginDao.getUserByid(userId);
			 */
			UserT userT = UserThreadLocal.get();
			long userId = userT.getId();
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			Map<String, Object> SelfDiagnosticTMap = new HashMap<>();
			SelfDiagnosticTMap.put("workorderid", orderId);
			SelfDiagnosticTMap.put("diagnosticdesc", diagnosticInfo);
			SelfDiagnosticTMap.put("inspectdesc", inspectInfo);
			SelfDiagnosticTMap.put("repairdesc", repairInfo);
			SelfDiagnosticTMap.put("replacepart", replaceComponent);
			if (replaceComponent == 1) { //当是否更换零部件为是时，更换配件信息字段必传
				SelfDiagnosticTMap.put("componentname", component);
			}
			//SelfDiagnosticTMap.put("componentcount",);
			SelfDiagnosticTMap.put("isworked", isWorked);
			SelfDiagnosticTMap.put("flag", 0);
			SelfDiagnosticTMap.put("createtime", currentTime);
			SelfDiagnosticTMap.put("creator", userT.getId());
			workOrderSelfDiagnosticTDao.insert(SelfDiagnosticTMap);
			if (workOrderT.getOrderChannel()!=1) {

			}
			//修改工单表状态为维修中  12--------- 逻辑已经修改   -----先调用开始维修接口（工单状态和通知已经发送），去除工单状态和通知
			//添加 自行诊断的标识
			String eAppVersion = MapUtils.getString(map, "eAppVersion", "");
			log.error("eAppVersion-----"+eAppVersion);
			Map<String, Object> workOrderMap = new HashMap<>();
			if (StringUtils.isBlank(eAppVersion) || eAppVersion.compareTo("3.28.0")<0) {
				workOrderMap.put("OrderStatus", 12); //维修中
			}
			workOrderMap.put("BulletFlag", 1);
			workOrderMap.put("Updator", userId);
			workOrderMap.put("UpdateTime", currentTime);
			workOrderMap.put("ID", orderId);
			//修改工单状态
			int updateNum = workOrderTDao.saveWorkOrderByUserAPPAppraise(workOrderMap);
			if (updateNum == 0) { //工单状态没修改成功
				obj.put("status", SMSEnum.type21.getIndex());
				obj.put("msg", SMSEnum.type21.getName());
				obj.put("data", "");
				// 主动回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				//返回客户
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}

			if (StringUtils.isBlank(eAppVersion) || eAppVersion.compareTo("3.28.0")<0) {
				//保存工单操作记录表
				saveOperation(orderId, userT.getId(), 12, "服务技师自行诊断服务工单", (String) map.get("locLon"),
						(String) map.get("locLat"), (String) map.get("location"), (String) map.get("IMEI"), 0,
						userT.getId(), currentTime);
//			保存负责人表
				map.put("workOrderId", orderId);
				List<WorkOrderPrincipalT> workOrderPrincipalTs = workOrderPrincipalTDao
						.getWorkOrderPrincipalTListByOrderId(map);
				if (CollectionUtils.isNotEmpty(workOrderPrincipalTs)) {
					for (WorkOrderPrincipalT workOrderPrincipalT : workOrderPrincipalTs) {
						savePrincipal(workOrderPrincipalT.getOrderId(), 12, workOrderPrincipalT.getIsPrincipal(),
								workOrderPrincipalT.getUserId(), userT.getId(), currentTime);
					}
				}

				//保存消息提醒表
				String smstext = "您的工单服务技师开始维修，工单号" + workOrderT.getOrderNo() + "，";
				if(workOrderT.getOrderChannel() == 1){
					smstext = smstext + "属于\"" + workOrderT.getSellType() + "\"" + (org.apache.commons.lang3.StringUtils.isNotBlank(workOrderT.getServiceSubtype()) ? "-" + workOrderT.getServiceSubtype() : "") + "，";
				}
				smstext = smstext + "请查看!";
				List<Map<String, Object>> notifyRecordTMapList = new ArrayList<>();
				//根据服务站id和服务渠道id获取区域服务经理手机号
				map.put("ServiceStationID", workOrderT.getServiceStationId());
				map.put("CompanyID", workOrderT.getOrderChannel());
				Map<String, Object> qygcsMap = new HashMap<>();
				if (workOrderT.getOrderChannel() == 1) { //DBU需求，只给指定的区域工程师推送消息
					qygcsMap = positionUserTDao.getDBUAreaManager(workOrderT.getId());
				}
				List<PositionUserT> positionUserTList = positionUserTDao.getPostUserTListByServiceStationIdCompanyId(map);
				if (CollectionUtils.isNotEmpty(positionUserTList)) {
					for (PositionUserT positionUserT : positionUserTList) {
						//如果是dbu的工单，并且能获取出来区域工程师
						if (workOrderT.getOrderChannel() == 1 && MapUtils.isNotEmpty(qygcsMap)) {
							//拿dbu指定的区域工程师手机号和上面的区域工程师集合循环比较，比较到了则推送，其他渠道工单不走此逻辑
							if (!(MapUtils.getString(qygcsMap, "DBEngineerPhone", "")
									.equals(positionUserT.getUserPhone()))) {
								continue;
							}
						}
						List<UserT> qyfwjls = loginDao.getUserByPhone(positionUserT.getUserPhone());
						if (CollectionUtils.isNotEmpty(qyfwjls)) {
							noticeService.push(6, 1, workOrderT.getId(), qyfwjls.get(0).getId(),
									qyfwjls.get(0).getUserName(), "新工单提醒", smstext, smstext, userT.getId());
						}
					}
				}
				//获取所有的站长
				List<UserT> ZZuserTList = userTDao.getStationMasterListByServiceStationId(workOrderT.getServiceStationId());
				if (CollectionUtils.isNotEmpty(ZZuserTList)) {
					for (UserT zzuserT : ZZuserTList) {
						noticeService.push(6, 1, workOrderT.getId(), zzuserT.getId(), zzuserT.getUserName(), "新工单提醒",
								smstext, smstext, userT.getId());
					}
				}
				/*
				 * //获取所有的信息员 List<UserT> XXYUserTList =
				 * userTDao.getMsgUserTByServiceStationId(map); if
				 * (CollectionUtils.isNotEmpty(XXYUserTList)) { for (UserT xxyuserT :
				 * XXYUserTList) { noticeService.push(6, 1, workOrderT.getId(),
				 * xxyuserT.getId(), xxyuserT.getUserName(), "新工单提醒", smstext, smstext,
				 * userT.getId()); } }
				 */
				// 终端用户
				// 通过手机号获取user_T表主键id
				List<UserT> customers = loginDao.getUserByPhone(workOrderT.getCustomerPhone());
				if (CollectionUtils.isNotEmpty(customers)) {
					noticeService.push(6, 1, workOrderT.getId(), customers.get(0).getId(), customers.get(0).getUserName(),
							"新工单提醒", smstext, smstext, userT.getId());
				}
				//保存消息提醒信息
				if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
					workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
				}

//			调用2.2.3 APP系统同步工单状态信息到CRM系统
				Map<String, Object> parameters1 = new HashMap<>();
				parameters1.put("orderNo", workOrderT.getOrderNo());
				parameters1.put("CRMNo", workOrderT.getOrderNoCrm());
				parameters1.put("billStatus", 12);
				parameters1.put("stationNo", "");
				parameters1.put("refuseReason", "");
				parameters1.put("timeOutReason", "");
				parameters1.put("lackOfPart", new ArrayList<>());
				if (workOrderT.getOrderChannel() == 1) {
					String clickStartRepairTime = redisClientUtils.get(RedisKeys.dbuStartRepairTime(orderId));
					if (StringUtils.isNotEmpty(clickStartRepairTime)) {
						parameters1.put("actionTime", clickStartRepairTime);
					} else {
						parameters1.put("actionTime", currentTime);
					}
				} else {
					parameters1.put("actionTime", currentTime);
				}
				parameters1.put("directorName", userT.getContact());
				parameters1.put("directorPhone", userT.getPhone());
				parameters1.put("planMileage", "");
				parameters1.put("travelMileage", "");
				parameters1.put("serviceCar", "");
				parameters1.put("positionLat", 0);
				parameters1.put("positionLon", 0);
				parameters1.put("drOrderNo", "");
				parameters1.put("drDiagnoseReport", "");
				try {
					CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
							companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
							platformServiceDao, redisClientUtils, parameters1,null);
					if (crmResponeEntity.getStatus() != 0) {
						log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
								+ crmResponeEntity.getMessage());
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
				}
			}


			//调用2.2.6 APP系统同步自行诊断信息到CRM系统
			Map<String, Object> parameters = new HashMap<>();
			parameters.put("orderNo", workOrderT.getOrderNo());
			parameters.put("CRMOrderNo", workOrderT.getOrderNoCrm());
			parameters.put("ESN", workOrderT.getESN());
			Map<String, Object> engineMsgMap = engineMsgDao.getSMNByESN(workOrderT.getESN());
			if (MapUtils.isNotEmpty(engineMsgMap)) {
				parameters.put("SMN", engineMsgMap.get("SMN"));
			} else {
				parameters.put("SMN", "");
			}
			parameters.put("diagnoseDescription", diagnosticInfo);
			parameters.put("checkTestRecord", inspectInfo);
			parameters.put("repairDescription", repairInfo);
			parameters.put("hasRenewalPart", replaceComponent);
			parameters.put("sendTSRReport", 0);
			parameters.put("renewalParts", component);
			parameters.put("hasSolved", isWorked);

			//添加自行诊断图片同步到crm
			try{
				Map<String, Object> workMap = workOrderTDao.getOrderById(orderId);
				int orderChannel = workOrderT.getOrderChannel();
				if (orderChannel == 1) {
					List<PictureManagementT> selfDiagnosisPics = pictureManagementTDao.getSelfDiagnosisPic(orderId);
					uploadPicturesImpl.syncPictureListToCCI(1L, selfDiagnosisPics, workMap, "1");
				}
			}catch (Exception e){
				e.printStackTrace();
				log.error("同步自行诊断照片至CRM失败!错误信息:" + e.getMessage(), e);
			}

			try {
				CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().activeDiagnostics(
						companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(), parameters,
						redisClientUtils);
				if (crmResponeEntity.getStatus() != 0) {
					log.error("同步自行诊断信息至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
							+ crmResponeEntity.getMessage());
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("同步自行诊断信息至CRM失败!错误信息:" + e.getMessage(), e);
			}
			String tsrData = readyTsrData(map, workOrderT, userT); //调用下面拼装tsr报告的公共方法
            log.info("调用是否触发tsr报告接口，参数为：" + tsrData);
			Map<String, Object> mapp = new HashMap<>();
			try {
				mapp = sceneTechnicalConfirmationServiceImpl.tsrTriggerReport(tsrData, map);
			} catch (Exception e) {
				String errorMsg = "技师自行诊断接口，调用是否触发tsr报告接口失败：" + MapUtils.getString(mapp, "msg", "");
				log.error(errorMsg);
			}
			int status = MapUtils.getIntValue(mapp, "status", -1); //调用接口返回的状态码
			if (status != 0) {
				String errorMsg = "技师自行诊断接口，调用是否触发tsr报告接口失败：" + MapUtils.getString(mapp, "msg", "");
				log.error(errorMsg);
			}
			obj.put("data", "");
			obj.put("status", 0);
			obj.put("msg", "success");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	//整理tsr报告数据
	String readyTsrData(Map<String, Object> map, WorkOrderT workOrderT, UserT userT) {
		JSONObject jsonObject = new JSONObject();
		int replaceComponent = Integer.parseInt(map.get("replaceComponent").toString());//更换零部件0：否；1：是
		String component = MapUtil.getMapValue(map, "component");//更换配件信息
		try {
			jsonObject.put("userId", userT.getId());
			jsonObject.put("workOrderId", workOrderT.getId());
			jsonObject.put("workOrderNo", workOrderT.getOrderNo());
			jsonObject.put("oem", workOrderT.getoEMName());
			List<Map<String, Object>> sceneTechnicalConfirmationMapList = sceneTechnicalConfirmationTDao
					.getSceneTechnicalConfirmationByOrderId(workOrderT.getId());
			//处理故障码症状信息
			if (CollectionUtils.isNotEmpty(sceneTechnicalConfirmationMapList)) {
				// long sceneTechnicalConfirmationId =
				// MapUtils.getLongValue(sceneTechnicalConfirmationMapList.get(0),"SceneTechnicalConfirmationId");
				jsonObject.put("smn", MapUtils.getString(sceneTechnicalConfirmationMapList.get(0), "SMN"));
				jsonObject.put("workHours", MapUtils.getString(sceneTechnicalConfirmationMapList.get(0), "WorkHours"));
				jsonObject.put("workMileages",
						MapUtils.getString(sceneTechnicalConfirmationMapList.get(0), "WorkMileages"));
				List<String> faultCodeList = new ArrayList<>();
				List<String> symptomList = new ArrayList<>();
				String faultCodes = MapUtils.getString(sceneTechnicalConfirmationMapList.get(0), "FaultCodes", "");
				if (StringUtils.isNotEmpty(faultCodes)) {
					faultCodeList = Arrays.asList(faultCodes.split(";"));
				}
				String symptomName = MapUtils.getString(sceneTechnicalConfirmationMapList.get(0), "SymptomName", "");
				if (StringUtils.isNotEmpty(symptomName)) {
					symptomList.add(symptomName);
				}
				if (CollectionUtils.isNotEmpty(faultCodeList)) {
					jsonObject.put("faultCodeList", faultCodeList);
				}
				if (CollectionUtils.isNotEmpty(symptomList)) {
					jsonObject.put("symptomList", symptomList);
				}
				/*
				 * List<Map<String,Object>> sceneTechnicalConfirmationFaultCodeSymptomTList =
				 * sceneTechnicalConfirmationFaultCodeSymptomTDao.
				 * getSceneTechnicalConfirmationFaultCodeSymptomTBySceneTechnicalConfirmationTId
				 * (sceneTechnicalConfirmationId);
				 * if(CollectionUtils.isNotEmpty(sceneTechnicalConfirmationFaultCodeSymptomTList
				 * )){ List<String> faultCodeList = new ArrayList<>(); List<String> symptomList
				 * = new ArrayList<>(); for(Map<String,Object>
				 * sceneTechnicalConfirmationFaultCodeSymptomT :
				 * sceneTechnicalConfirmationFaultCodeSymptomTList){ int type =
				 * MapUtils.getIntValue(sceneTechnicalConfirmationFaultCodeSymptomT,"Type");
				 * //1:故障码，2:症状 if(type == 1){ faultCodeList.add(MapUtils.getString(
				 * sceneTechnicalConfirmationFaultCodeSymptomT,"FaultCode","")); }else{
				 * symptomList.add(MapUtils.getString(
				 * sceneTechnicalConfirmationFaultCodeSymptomT,"SymptomName","")); } }
				 * if(CollectionUtils.isNotEmpty(faultCodeList)){
				 * jsonObject.put("faultCodeList",faultCodeList); }
				 * if(CollectionUtils.isNotEmpty(symptomList)){
				 * jsonObject.put("symptomList",symptomList); } }
				 */
			}
			//处理更新的零件号零件名称信息
			if (replaceComponent == 1 && StringUtils.isNotEmpty(component)) {
				//Aaa,BBB,1;Ccc ,Ddd,2      格式为零件号,零件名称,数量
				List<String> partNoList = new ArrayList<>();
				List<String> partNameList = new ArrayList<>();
				String[] components = component.split(";");
				if (components.length != 0) {
					for (String componentStr : components) {
						String partNo = componentStr.substring(0, componentStr.indexOf(","));
						String partName = componentStr.substring(componentStr.indexOf(",") + 1,
								componentStr.lastIndexOf(","));
						partNoList.add(partNo);
						partNameList.add(partName);
					}
				}
				jsonObject.put("partNoList", partNoList);
				jsonObject.put("partNameList", partNameList);
			}
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return jsonObject.toString();
	}

	//获取自行诊断详情接口(DBU)
	@Transactional
	@Override
	public ModelAndView getSelfDiagnosticDetail(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			if (!map.containsKey("orderId")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			long orderId = MapUtils.getLongValue(map, "orderId");
			Map<String, Object> selfDiagnosticDetailMap = workOrderSelfDiagnosticTDao.getSelfDiagnosticDetail(orderId);
			obj.put("data", new JSONObject().put("selfDiagnosticDetail", selfDiagnosticDetailMap));
			obj.put("status", 0);
			obj.put("msg", "success");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	//CCEC400审核不通过驳回时   根据工单来源让对应用户更新工单信息  (用户报单让用户更新    服务站报单让服务站站长信息员更新)
	@Transactional
	@Override
	public ModelAndView updateWorkOrderMsg(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			UserT userT = UserThreadLocal.get();
			int orderStatus = 24;
			map.put("updator", userT.getId());
			String currentTime = LocalTimeUtil.getRealCurrentTime(); //获取当前时间
			map.put("updateTime", currentTime);
			map.put("orderStatus", orderStatus);
			if (!map.containsKey("orderId")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (!map.containsKey("contactName")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "联系人不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (!map.containsKey("contactPhone")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "联系人电话不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (!map.containsKey("customerCompanyName")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "客户单位不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (!map.containsKey("customerComplaint")) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "用户服务需求不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			String locLon = MapUtils.getString(map, "locLon");
			String locLat = MapUtils.getString(map, "locLat");
			String location = MapUtils.getString(map, "location");
			String IMEI = MapUtils.getString(map, "IMEI");
			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(MapUtils.getLongValue(map, "orderId"));
			int orderSource = workOrderT.getOrderSource();
			map.put("orderSource", orderSource);
			//用户报单更新现场人和现场人电话字段   服务站报单更新用户和用户电话字段
			int updateWorkOrderResult = workOrderTDao.updateWorkOrderMsg(map);
			if (updateWorkOrderResult == 0) { //工单状态没修改成功
				obj.put("status", SMSEnum.type21.getIndex());
				obj.put("msg", SMSEnum.type21.getName());
				obj.put("data", "");
				//返回客户
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			//调用2.2.3 APP系统同步工单状态信息到CRM系统
			Map<String, Object> parameters1 = new HashMap<>();
			parameters1.put("orderNo", workOrderT.getOrderNo());
			parameters1.put("CRMNo", workOrderT.getOrderNoCrm());
			parameters1.put("billStatus", orderStatus);
			parameters1.put("actionTime", currentTime);
			parameters1.put("directorName", userT.getContact());
			parameters1.put("directorPhone", userT.getPhone());
			parameters1.put("positionLat", locLat);
			parameters1.put("positionLon", locLon);
			parameters1.put("phoneIMEI", IMEI);
			parameters1.put("location", location);
			CompanyT ccecChannelCompany = companyTDao.getCompanyInfoByCompanyNo("CCEC");
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
				parameters1.put("CCSSComplainerOrderNo", workOrderT.getOrderNoCrm());
				parameters1.put("CCSSOrderNo", workOrderT.getCCSSOrderNo());
				parameters1.put("customerName", workOrderT.getCustomerName());
				parameters1.put("customerPhone", workOrderT.getCustomerPhone());
				parameters1.put("customerCompany", workOrderT.getCustomerCompanyName());
				parameters1.put("faultDesc", workOrderT.getCustomerComplaint());
				Map<String, Object> sSRepair = serviceStationDao.getStationNoAndNameByStationIdAndCompanyId(
						workOrderT.getServiceStationId(), workOrderT.getOrderChannel());
				if (org.apache.commons.collections.MapUtils.isNotEmpty(sSRepair)) {
					parameters1.put("stationNo", sSRepair.get("BusinessNo"));
					parameters1.put("stationName", sSRepair.get("StationName"));
				} else {
					parameters1.put("stationNo", "");
					parameters1.put("stationName", "");
				}
			}
			try {
				CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
						companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
						platformServiceDao, redisClientUtils, parameters1,null);
				if (crmResponeEntity.getStatus() != 0) {
					log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:"
							+ crmResponeEntity.getMessage());
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
			}
			//插入工单操作记录表
			saveOperation(workOrderT.getId(), userT.getId(), orderStatus, "用户或服务站更新工单，提交ccec400审核", locLon, locLat,
					location, IMEI, 0, userT.getId(), currentTime);
			List<Map<String, Object>> AreaManagerMapList = new ArrayList<>();
			if (orderSource == 0) { //工单来源是用户在线报修    更新完工单   负责人是所有400
				AreaManagerMapList = workOrderRepairDao.getCCECAreaManager(workOrderT.getOrderChannel());
			}
			if (orderSource == 1) { //工单来源是服务站在线报修    更新完工单   负责人是服务站对应的400
				map.put("ServiceStationId", workOrderT.getServiceStationId());
				map.put("OrderChannel", workOrderT.getOrderChannel());
				AreaManagerMapList = workOrderRepairDao.getAreaManager(map);
			}
			//保存消息提醒集合
			String msgbody = msgbodyCCEC;
			String msg = "";
			if (StringUtils.isNotEmpty(workOrderT.getCCSSOrderNo())) {
				msg = workOrderT.getOrderNo() + "（FW号" + workOrderT.getCCSSOrderNo() + "）";
				msgbody = String.format(msgbody, msg);
			} else {
				msgbody = String.format(msgbody, workOrderT.getOrderNo());
			}
			List<Map<String, Object>> notifyRecordTMapList = new ArrayList<>();
			if (CollectionUtils.isNotEmpty(AreaManagerMapList)) {
				for (Map<String, Object> AreaManagerMap : AreaManagerMapList) {
					long receiverId = MapUtils.getLongValue(AreaManagerMap, "ID");
					String receiverUserName = MapUtils.getString(AreaManagerMap, "UserName");
					String phone = MapUtils.getString(AreaManagerMap, "phone", "");
					savePrincipal(workOrderT.getId(), orderStatus, 1, receiverId, userT.getId(), currentTime);
					noticeService.push(2, 1, workOrderT.getId(), receiverId, receiverUserName, "新工单提醒", msgbody,
							msgbody, userT.getId());
					SmsUtils.sendMessage(phone, msgbody);
					notifyRecordTMapList.add(saveMsgOperation(workOrderT.getId(), 2, 1, receiverId, msgbody, 1,
							currentTime, "", userT.getId()));
				}
			}
			if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
				workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
			}
			obj.put("data", "");
			obj.put("status", 0);
			obj.put("msg", "success");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			//主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	//待更新的子方法
	public void sonMethod(WorkOrderT workOrderT, int orderStatus, String currentTime, UserT userT,
						  Map<String, Object> map, int orderSource) {
		//调用2.2.3 APP系统同步工单状态信息到CRM系统
		Map<String, Object> parameters1 = new HashMap<>();
		parameters1.put("orderNo", workOrderT.getOrderNo());
		parameters1.put("CRMNo", workOrderT.getOrderNoCrm());
		parameters1.put("billStatus", orderStatus);
		parameters1.put("actionTime", currentTime);
		parameters1.put("directorName", userT.getContact());
		parameters1.put("directorPhone", userT.getPhone());
		parameters1.put("positionLat", 0);
		parameters1.put("positionLon", 0);
		CompanyT ccecChannelCompany = companyTDao.getCompanyInfoByCompanyNo("CCEC");
		if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
			parameters1.put("CCSSComplainerOrderNo", workOrderT.getOrderNoCrm());
			parameters1.put("CCSSOrderNo", workOrderT.getCCSSOrderNo());
			parameters1.put("customerName", workOrderT.getCustomerName());
			parameters1.put("customerPhone", workOrderT.getCustomerPhone());
			parameters1.put("customerCompany", workOrderT.getCustomerCompanyName());
			parameters1.put("faultDesc", workOrderT.getCustomerComplaint());
			Map<String, Object> sSRepair = serviceStationDao.getStationNoAndNameByStationIdAndCompanyId(
					workOrderT.getServiceStationId(), workOrderT.getOrderChannel());
			if (org.apache.commons.collections.MapUtils.isNotEmpty(sSRepair)) {
				parameters1.put("stationNo", sSRepair.get("BusinessNo"));
				parameters1.put("stationName", sSRepair.get("StationName"));
			} else {
				parameters1.put("stationNo", "");
				parameters1.put("stationName", "");
			}
		}
		try {
			CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
					companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
					platformServiceDao, redisClientUtils, parameters1,null);
			if (crmResponeEntity.getStatus() != 0) {
				log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:" + crmResponeEntity.getMessage());
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
		}
		//插入工单操作记录表
		saveOperation(workOrderT.getId(), userT.getId(), orderStatus, "用户或服务站更新工单，提交ccec400审核",
				MapUtils.getString(map, "locLon"), MapUtils.getString(map, "locLat"),
				MapUtils.getString(map, "location"), MapUtils.getString(map, "IMEI"), 0, userT.getId(), currentTime);
		List<Map<String, Object>> AreaManagerMapList = new ArrayList<>();
		if (orderSource == 0) { //工单来源是用户在线报修    更新完工单   负责人是所有400
			AreaManagerMapList = workOrderRepairDao.getCCECAreaManager(workOrderT.getOrderChannel());
		}
		if (orderSource == 1) { //工单来源是服务站在线报修    更新完工单   负责人是服务站对应的400
			map.put("ServiceStationId", workOrderT.getServiceStationId());
			map.put("OrderChannel", workOrderT.getOrderChannel());
			AreaManagerMapList = workOrderRepairDao.getAreaManager(map);
		}
		//保存消息提醒集合
		String msgbody = msgbodyCCEC;
		String msg = "";
		if (StringUtils.isNotEmpty(workOrderT.getCCSSOrderNo())) {
			msg = workOrderT.getOrderNo() + "（FW号" + workOrderT.getCCSSOrderNo() + "）";
			msgbody = String.format(msgbody, msg);
		} else {
			msgbody = String.format(msgbody, workOrderT.getOrderNo());
		}
		List<Map<String, Object>> notifyRecordTMapList = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(AreaManagerMapList)) {
			for (Map<String, Object> AreaManagerMap : AreaManagerMapList) {
				long receiverId = MapUtils.getLongValue(AreaManagerMap, "ID");
				String receiverUserName = MapUtils.getString(AreaManagerMap, "UserName");
				String phone = MapUtils.getString(AreaManagerMap, "phone", "");
				savePrincipal(workOrderT.getId(), orderStatus, 1, receiverId, userT.getId(), currentTime);
				noticeService.push(2, 1, workOrderT.getId(), receiverId, receiverUserName, "新工单提醒", msgbody, msgbody,
						userT.getId());
				SmsUtils.sendMessage(phone, msgbody);
				notifyRecordTMapList.add(saveMsgOperation(workOrderT.getId(), 2, 1, receiverId, msgbody, 1, currentTime,
						"", userT.getId()));
			}
		}
		if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
			workOrderRepairDao.saveMsgOperation(notifyRecordTMapList);
		}
	}

	//插入工单操作记录表公共方法
	public void saveOperation(long OrderId, long ProcessorId, int OrderStatus, String ProcessComment, String ProLocLon,
							  String ProLocLat, String ProLocation, String IMEI, int Flag, long Creator, String CreateTime) {
		doSaveOperation(OrderId, ProcessorId, OrderStatus, ProcessComment, ProLocLon, ProLocLat, ProLocation, IMEI,
				Flag, Creator, CreateTime, null);
	}

	// 插入工单操作记录表公共方法
	public void doSaveOperation(long OrderId, long ProcessorId, int OrderStatus, String ProcessComment,
			String ProLocLon, String ProLocLat, String ProLocation, String IMEI, int Flag, long Creator,
			String CreateTime, String rejectedReason) {
		// 插入并保存工单操作记录表数据
		Map<String, Object> workOrderFlowTMap = new HashMap<String, Object>(); // 新建工单操作记录对象
		workOrderFlowTMap.put("OrderId", OrderId); // 工单id
		workOrderFlowTMap.put("ProcessorId", ProcessorId); // 处理人
		workOrderFlowTMap.put("OrderStatus", OrderStatus); // 工单状态
		workOrderFlowTMap.put("ProcessComment", ProcessComment); // 操作备注
		workOrderFlowTMap.put("ProLocLon", ProLocLon); // 经度
		workOrderFlowTMap.put("ProLocLat", ProLocLat); // 纬度
		workOrderFlowTMap.put("ProLocation", ProLocation); // 操作地点
		workOrderFlowTMap.put("IMEI", IMEI); // 手机串号
		workOrderFlowTMap.put("Flag", Flag); // 是否有效(0为是，1为否)
		workOrderFlowTMap.put("Creator", Creator); // 创建人
		workOrderFlowTMap.put("CreateTime", CreateTime); // 处理时间
		workOrderFlowTMap.put("Remark", rejectedReason); // 异常关闭，400驳回原因
		workOrderRepairDao.saveOperation(workOrderFlowTMap); // 插入并保存工单操作记录数据
	}

	// 插入工单操作记录表公共方法
	public void saveOperationByFinishTime(long OrderId, long ProcessorId, int OrderStatus, String ProcessComment,
			String ProLocLon, String ProLocLat, String ProLocation, String IMEI, int Flag, long Creator,
			String finishTime, String createTime) {
		// 插入并保存工单操作记录表数据
		Map<String, Object> workOrderFlowTMap = new HashMap<String, Object>(); // 新建工单操作记录对象
		workOrderFlowTMap.put("OrderId", OrderId); // 工单id
		workOrderFlowTMap.put("ProcessorId", ProcessorId); // 处理人
		workOrderFlowTMap.put("OrderStatus", OrderStatus); // 工单状态
		workOrderFlowTMap.put("ProcessComment", ProcessComment); // 操作备注
		workOrderFlowTMap.put("ProLocLon", ProLocLon); // 经度
		workOrderFlowTMap.put("ProLocLat", ProLocLat); // 纬度
		workOrderFlowTMap.put("ProLocation", ProLocation); // 操作地点
		workOrderFlowTMap.put("IMEI", IMEI); // 手机串号
		workOrderFlowTMap.put("Flag", Flag); // 是否有效(0为是，1为否)
		workOrderFlowTMap.put("Creator", Creator); // 创建人
		workOrderFlowTMap.put("UpdateTime", createTime); // 处理时间
		workOrderFlowTMap.put("CreateTime", finishTime); // 维修完成时间
		workOrderRepairDao.saveOperation(workOrderFlowTMap); // 插入并保存工单操作记录数据
	}

	//插入消息提醒表公共方法
	public Map<String, Object> saveMsgOperation(Long workOrderId, int Function, int Category, Long ReceiverId,
												String Content, int SendType, String SendTime, String ExceptionInfo, long Creator) {
		Map<String, Object> notifyRecordTMap = new HashMap<String, Object>();
		notifyRecordTMap.put("OrderId", workOrderId);
		notifyRecordTMap.put("Function", Function);
		notifyRecordTMap.put("Category", Category);
		notifyRecordTMap.put("ReceiverId", ReceiverId); //接收人
		notifyRecordTMap.put("Content", Content);
		notifyRecordTMap.put("SendType", SendType);
		notifyRecordTMap.put("SendTime", SendTime);
		notifyRecordTMap.put("Status", 1);
		notifyRecordTMap.put("ExceptionInfo", ExceptionInfo);
		notifyRecordTMap.put("IsRead", 0);
		notifyRecordTMap.put("Flag", 0);
		notifyRecordTMap.put("Creator", Creator);
		notifyRecordTMap.put("CreateTime", SendTime);
		return notifyRecordTMap;
	}

	//插入工单负责人表公共方法
	@Override
	public void savePrincipal(Long workOrderId, int OrderStatus, int IsPrincipal, long PrincipalId, long ProcessorId,
							  String CreateTime) {
		Map<String, Object> workOrderPrincipalTMap = new HashMap<String, Object>();
		workOrderPrincipalTMap.put("OrderId", workOrderId);
		workOrderPrincipalTMap.put("OrderStatus", OrderStatus); //工单状态
		workOrderPrincipalTMap.put("IsPrincipal", IsPrincipal); //是主负责人
		workOrderPrincipalTMap.put("PrincipalId", PrincipalId); //负责人主键id
		workOrderPrincipalTMap.put("Audited", 0);
		workOrderPrincipalTMap.put("Flag", 0);
		workOrderPrincipalTMap.put("ProcessorId", ProcessorId); //创建人
		workOrderPrincipalTMap.put("CreateTime", CreateTime);
		workOrderRepairDao.savePrincipal(workOrderPrincipalTMap); //插入并保存工单负责人表数据
	}

	@Override
	public ModelAndView clickRepairForDBU(Map<String, Object> map) {
		Long orderId = MapUtils.getLong(map, "orderId");
		if (NumberUtils.isPositiveNum(orderId)) {
			if (!redisClientUtils.exists(RedisKeys.dbuStartRepairTime(orderId))) {
				redisClientUtils.set(RedisKeys.dbuStartRepairTime(orderId), LocalTimeUtil.getRealCurrentTime(),
						60 * 60 * 24 * 30);
			}
		}
		ParameterTool.writeSuccessResponse(RequestContextHolder.getResponse());
		return null;
	}

	@Override
	@Transactional
	public void updateWorkOrderStatus(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		UserT userT = UserThreadLocal.get();
		Long orderId = MapUtils.getLong(map, "orderId");
		WorkOrderT orderT = workOrderTDao.getWorkOrderTByOrderId(orderId);
		if (null != orderT) {
			Integer orderStatus = MapUtils.getInteger(map, "orderStatus", 0);
			Map<String, Object> updateMap = new HashMap<>();
			updateMap.put("ID", orderId);
			// 原工单状态为待派服务技师或者技师已拒单，并且请求更新为服务中，将工单状态置为服务中
			if ((orderT.getOrderStatus() == Dictionaries.OrderStatus_06.getIndex()
					|| orderT.getOrderStatus() == Dictionaries.OrderStatus_09.getIndex())
					&& orderStatus.equals(Dictionaries.OrderStatus_35.getIndex())) {
				updateMap.put("OrderStatus", orderStatus);
				String orderComments = MapUtils.getString(map, "orderComments");
				String positionLon = MapUtils.getString(map, "positionLon");
				String positionLat = MapUtils.getString(map, "positionLat");
				String positionLocation = MapUtils.getString(map, "positionLocation");
				String current = LocalTimeUtil.getRealCurrentTime();
				updateMap.put("Updator", userT.getId());
				updateMap.put("UpdateTime", current);
				// 更新工单状态
				workOrderTDao.updateByPrimaryKeySelective(updateMap);
				// 更新流水
				saveOperation(orderId, userT.getId(), orderStatus, orderComments, positionLon, positionLat,
						positionLocation, "", 0, userT.getId(), current);
				// 更新负责人
				savePrincipal(orderId, orderStatus, 1, userT.getId(), userT.getId(), current);
			} else if (orderT.getOrderStatus() == Dictionaries.OrderStatus_35.getIndex()
					&& orderStatus.equals(Dictionaries.OrderStatus_06.getIndex())) {
				// 原工单状态为服务中，并且请求更新为待派服务技师，将工单状态置为待派服务技师
				updateMap.put("OrderStatus", orderStatus);
				String orderComments = MapUtils.getString(map, "orderComments");
				String positionLon = MapUtils.getString(map, "positionLon");
				String positionLat = MapUtils.getString(map, "positionLat");
				String positionLocation = MapUtils.getString(map, "positionLocation");
				String current = LocalTimeUtil.getRealCurrentTime();
				updateMap.put("Updator", userT.getId());
				updateMap.put("UpdateTime", current);
				// 更新工单状态
				workOrderTDao.updateByPrimaryKeySelective(updateMap);
				// 更新流水
				saveOperation(orderId, userT.getId(), orderStatus, orderComments, positionLon, positionLat,
						positionLocation, "", 0, userT.getId(), current);
				// 更新负责人
				//savePrincipal(orderId,orderStatus,1,userT.getId(),userT.getId(),current);
			} else if (orderT.getOrderStatus() == Dictionaries.OrderStatus_35.getIndex()
					&& orderStatus.equals(Dictionaries.OrderStatus_08.getIndex())) {
				// 原工单状态为服务中，并且请求更新为技师已接单，将工单状态置为技师已接单
				updateMap.put("OrderStatus", orderStatus);
				String orderComments = MapUtils.getString(map, "orderComments");
				String positionLon = MapUtils.getString(map, "positionLon");
				String positionLat = MapUtils.getString(map, "positionLat");
				String positionLocation = MapUtils.getString(map, "positionLocation");
				String current = LocalTimeUtil.getRealCurrentTime();
				updateMap.put("Updator", userT.getId());
				updateMap.put("UpdateTime", current);
				// 更新工单状态
				workOrderTDao.updateByPrimaryKeySelective(updateMap);
				// 更新流水
				saveOperation(orderId, userT.getId(), orderStatus, orderComments, positionLon, positionLat,
						positionLocation, "", 0, userT.getId(), current);
				// 更新负责人
				savePrincipal(orderId, orderStatus, 1, userT.getId(), userT.getId(), current);
			} else {
				ParameterTool.writeResponse(response, 2, "非法状态请求");
			}
			//同步工单状态至crm
			syncDBUOrderStatusCRM(map);
			ParameterTool.writeSuccessResponse(response);
		} else {
			ParameterTool.writeResponse(response, 1, "非法操作");
		}
	}

	//updateWorkOrderStatus方法dbu同步工单状态至crm     单独提出来同步给crm的逻辑
	void syncDBUOrderStatusCRM(Map<String, Object> map) {
		UserT userT = UserThreadLocal.get();
		String positionLon = MapUtils.getString(map, "positionLon");
		String positionLat = MapUtils.getString(map, "positionLat");
		long orderId = MapUtils.getLong(map, "orderId");
		int orderStatus = MapUtils.getIntValue(map, "orderStatus", 0);
		Map<String, Object> workOrderMap = workOrderTDao.getOrderById(orderId);
		String orderNo = MapUtils.getString(workOrderMap, "OrderNo", "");
		String CRMNo = MapUtils.getString(workOrderMap, "OrderNoCrm", "");
		long serviceStationId = MapUtils.getLongValue(workOrderMap, "ServiceStationId");
		long orderChannel = MapUtils.getLongValue(workOrderMap, "OrderChannel");

		// TODO mark
		//调用2.2.3 APP系统同步工单状态信息到CRM系统
		Map<String, Object> parameters = new HashMap<>();
		parameters.put("orderNo", orderNo);
		parameters.put("CRMNo", CRMNo);
		parameters.put("billStatus", orderStatus);
		Map<String, Object> sSRepair = serviceStationDao.getSSRepairByStationIdAndCompanyId(serviceStationId,
				orderChannel);
		if (MapUtils.isNotEmpty(sSRepair)) {
			parameters.put("stationNo", sSRepair.get("BusinessNo"));
		} else {
			parameters.put("stationNo", "");
		}
		parameters.put("refuseReason", "");
		parameters.put("timeOutReason", "");
		parameters.put("lackOfPart", new ArrayList<>());
		parameters.put("actionTime", LocalTimeUtil.getRealCurrentTime());
		parameters.put("directorName", userT.getContact());
		parameters.put("directorPhone", userT.getPhone());
		parameters.put("planMileage", "");
		parameters.put("travelMileage", "");
		parameters.put("serviceCar", "");
		parameters.put("positionLat", positionLat);
		parameters.put("positionLon", positionLon);
		parameters.put("drOrderNo", "");
		parameters.put("drDiagnoseReport", "");
		try {
			CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
					companyTDao.getCompanyInfoByCompanyID(orderChannel).getCompanyNo(), platformServiceDao,
					redisClientUtils, parameters,null);
			if (crmResponeEntity.getStatus() != 0) {
				log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:" + crmResponeEntity.getMessage());
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
		}

	}

	@Override
	public void getWorkOrderForMT(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		Long orderId = MapUtils.getLong(map, "orderId");
		WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(orderId);
		if (null != workOrderT) {
			ServiceStationT serviceStationT = serviceStationDao
					.findServiceStationByID(String.valueOf(workOrderT.getServiceStationId()));
			if (null != serviceStationT) {
				Map<String, Object> orderResponse = new HashMap<>();
				orderResponse.put("orderId", workOrderT.getId());
				orderResponse.put("orderNo", workOrderT.getOrderNo());
				orderResponse.put("ESN", workOrderT.getESN());
				orderResponse.put("OEM", workOrderT.getoEMName());
				orderResponse.put("OEMId", workOrderT.getoEMID());
				orderResponse.put("marketType", workOrderT.getMarketType());
				orderResponse.put("application", workOrderT.getApplication());

				orderResponse.put("createTime", workOrderT.getCreateTime());
				orderResponse.put("faultDesc", workOrderT.getCustomerComplaint());
				// 经销商地点
				orderResponse.put("stationLon", serviceStationT.getPositionLon());
				orderResponse.put("stationLat", serviceStationT.getPositionLat());
				orderResponse.put("stationLocation", serviceStationT.getAddress());
				// 维修地点
				orderResponse.put("repairLon", workOrderT.getLocLon());
				orderResponse.put("repairLat", workOrderT.getLocLat());
				orderResponse.put("repairLocation", workOrderT.getLocation());
				// 服务工单来源
				orderResponse.put("orderSource", workOrderT.getOrderSource());
				ParameterTool.writeSuccessResponse(response, orderResponse);
			} else {
				ParameterTool.writeResponse(response, 2, "查无相关服务站");
			}
		} else {
			ParameterTool.writeResponse(response, 1, "非法操作");
		}
	}

	//站长获取本服务站下所有代派技师服务工单列表
	@Override
	public ModelAndView getWaitAssignTechnicianOrderList(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			UserT userT = UserThreadLocal.get();
			long serviceStationId = userT.getServiceStationID();
			if (serviceStationId == 0) { //不是服务站人员
				obj.put("status", SMSEnum.type50.getIndex());
				obj.put("msg", SMSEnum.type50.getName());
				obj.put("data", "");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			} else {
				List<Map<String, Object>> orderList = workOrderTDao.getWaitAssignTechnicianOrderList(serviceStationId);
				Map<String, Object> dataMap = new HashMap<>();
				dataMap.put("workOrderList", orderList);
				obj.put("data", dataMap);
				obj.put("status", 0);
				obj.put("msg", "success");
				ParameterTool.writeResponse(response, obj.toString());
			}
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			log.error(e.getMessage(), e);
		}
		return null;
	}

	//根据主动升级工单id或者服务工单id获取服务工单详情
	@Override
	public ModelAndView getWorkOrderMsg(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		int type = MapUtils.getIntValue(map, "type", -1); // (1:服务工单     2:主动升级单)
		long orderId = MapUtils.getLongValue(map, "orderId", -1);
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			if (type == -1 || orderId == -1) { //缺少必要参数
				obj.put("status", SMSEnum.type17.getIndex());
				obj.put("msg", SMSEnum.type17.getName());
				obj.put("data", "");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			} else {
				long workOrderId = orderId; //重新声明服务工单id   如果是主动升级工单 下面赋值
				if (type == 2) { //主动升级工单
					EscalationOrderT escalationOrderT = escalationOrderTDao.selectByPrimaryKey(orderId);
					if (null != escalationOrderT) {
						workOrderId = escalationOrderT.getWorkOrderId();
					}
				}
				Map<String, Object> orderMsgMap = workOrderTDao.getWorkOrderMsgById(workOrderId);
				Map<String, Object> returnMap = new HashMap<>();
				returnMap.put("orderInfo", orderMsgMap);
				obj.put("data", returnMap);
				obj.put("status", 0);
				obj.put("msg", "success");
				ParameterTool.writeResponse(response, obj.toString());
			}
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			log.error(e.getMessage(), e);
		}
		return null;
	}

	@Override
	public ModelAndView getMTMsgByWorkOrder(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		Map<String, Object> returnMap = new HashMap<>();
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			Map<String, Object> contentJsonMap = JSON.parseObject(MapUtils.getString(map, "contentJson"), Map.class);
			if (contentJsonMap.containsKey("serviceStationIds")) { //获取服务站信息
				List<Map<String, Object>> serviceStationList = new ArrayList<>();
				List<Long> serviceStationIds = (List<Long>) contentJsonMap.get("serviceStationIds");
				if (CollectionUtils.isNotEmpty(serviceStationIds)) {
					serviceStationList = serviceStationDao.getServiceStationInfoListByIds(serviceStationIds);
				}
				returnMap.put("serviceStationList", serviceStationList);
			}
			if (contentJsonMap.containsKey("userIds")) { //获取用户信息
				List<Map<String, Object>> usersInfoList = new ArrayList<>();
				List<Long> userIds = (List<Long>) contentJsonMap.get("userIds");
				if (CollectionUtils.isNotEmpty(userIds)) {
					usersInfoList = userTDao.getUserInfoListByIds(userIds);
				}
				returnMap.put("usersInfoList", usersInfoList);
			}
			if (contentJsonMap.containsKey("workOrderIds")) { //获取工单信息
				List<Map<String, Object>> workOrderInfoList = new ArrayList<>();
				List<Long> workOrderIds = (List<Long>) contentJsonMap.get("workOrderIds");
				if (CollectionUtils.isNotEmpty(workOrderIds)) {
					workOrderInfoList = workOrderTDao.getWorkOrderInfoListByIds(workOrderIds);
				}
				returnMap.put("workOrderInfoList", workOrderInfoList);
			}

			if (contentJsonMap.containsKey("serviceStationName") || contentJsonMap.containsKey("serviceStationNo")) {
				List<Long> serviceStationIds = new ArrayList<>();
				String serviceStationName = MapUtils.getString(contentJsonMap, "serviceStationName", "");
				String serviceStationNo = MapUtils.getString(contentJsonMap, "serviceStationNo", "");
				if (StringUtils.isNotEmpty(serviceStationName) || StringUtils.isNotEmpty(serviceStationNo)) {
					serviceStationIds = serviceStationDao.getServiceStationIdList(serviceStationName, serviceStationNo);
				}
				returnMap.put("serviceStationIdList", serviceStationIds);
			}

			obj.put("data", returnMap);
			obj.put("status", 0);
			obj.put("msg", "success");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			log.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 400审核通过服务技师关闭的服务工单
	 */
	@Override
	@Transactional
	public void closeWorkOrderById(CloseWorkOrderCondition condition) {
		UserT user = UserThreadLocal.get();
		String createTime = LocalTimeUtil.getRealCurrentTime();

		// 设置服务工单的状态为异常关闭
		condition.setStatus(16);
		condition.setUpdator(user.getId());
		condition.setUpdateTime(createTime);
		int count = workOrderTDao.updateWorkOrderStatusById(condition);

		if (count > 0) {
			WorkOrderT workOrder = null;
			WorkOrderT oldWo = workOrderTDao.getWorkOrderByOrderId(condition.getId());
			// 此参数不空且有效时，说明400对异常关闭的工单进行改派中
			Long serviceStationId = condition.getServiceStationId();
			if (NumberUtils.isPositiveNum(serviceStationId)) {

				// 生成新的服务工单
				WorkOrderT newWo = BeanUtils.convert(oldWo, WorkOrderT.class);
				/**
				 * <p>
				 *     自动生成工单编号，由 redis 更改为 sqlServer
				 * </p>
				 */
				String workOrderNo = OrderGenerateUtil.getWorkOrderNo();
				newWo.setOrderNo(workOrderNo);
				newWo.setCCSSOrderNo(null);
				newWo.setOrderStatus(4);
				newWo.setUpdator(user.getId());
				newWo.setUpdateTime(createTime);
				newWo.setServiceStationId(condition.getServiceStationId());

				if (condition.getGuessDistance() != null) {
					newWo.setGuessDistance(condition.getGuessDistance());
				}

				newWo.setCreator(user.getId());
				newWo.setCreateTime(oldWo.getCreateTime());
				newWo.setRelOrderIdOld(condition.getId());
				workOrderTDao.insertWorkOrderSelective(newWo);

				// 将旧工单绑定新工单
				oldWo.setRelOrderId(newWo.getId());
				workOrderTDao.updateEntityById(oldWo);
				// 生成负责人数据
				List<UserT> users = userTDao.getStationMasterListByServiceStationId(condition.getServiceStationId());
				if (CollectionUtils.isNotEmpty(users)) {
					List<WorkOrderPrincipalT> list = users.stream().map(e -> {
						WorkOrderPrincipalT wop = new WorkOrderPrincipalT();
						wop.setOrderId(newWo.getId());
						wop.setOrderStatus(newWo.getOrderStatus());
						wop.setIsPrincipal(1);
						wop.setUserId(e.getId());
						wop.setFlag(0);
						wop.setCreator(user.getId());
						wop.setCreateTime(createTime);
						return wop;
					}).collect(Collectors.toList());
					workOrderPrincipalTDao.insertBatchSelective(list);
				}

				// 生成流水
				saveOperation(newWo.getId(), user.getId(), newWo.getOrderStatus(), "异常关闭400审核通过并指派服务站",
						condition.getLocLon(), condition.getLocLat(), condition.getLocation(), condition.getImei(), 0,
						user.getId(), createTime);

				workOrder = newWo;
			}

			// 生成流水
			saveOperation(condition.getId(), user.getId(), 16, oldWo.getCloseReason(), condition.getLocLon(),
					condition.getLocLat(), condition.getLocation(), condition.getImei(), 0, user.getId(), createTime);

			// TODO 同步服务工单状态到CRM
			syncWorkOrderStatus(condition.getId(), user, 1, null);

			if (!Objects.isNull(workOrder)) {

				// 只有保修类的服务才同步到CRM
				Integer requestType = oldWo.getRequestType();

				if (requestType != null && requestType.equals(1)) {
					// TODO 同步新服务工单状态到CRM
					String fwNo = syncWorkOrderStatus(workOrder.getId(), user, 1, null);
					if (StringUtils.isNotBlank(fwNo)) {
						// 将FWNO保存到服务工单上
						workOrder.setCCSSOrderNo(fwNo);
						workOrder.setUpdateTime(createTime);
						workOrder.setUpdator(user.getId());
						workOrderTDao.updateWorkOrderById(workOrder);
					} else {
						ParameterTool.writeErrorResponse(RequestContextHolder.getResponse(), -43);
						throw new RuntimeException("服务工单异常关闭，同步新服务工单状态到CRM失败");
					}

				}



				// TODO ===消息推送给旧服务站相关人员（注：如果工单是技师关闭则消息也会推送给技师）
				messagePushUtils.pushMessageByServiceStationId(oldWo.getId(), oldWo.getServiceStationId(),
						String.format("您有工单异常关闭审核通过，工单号%s，请查看。", oldWo.getOrderNo()), oldWo.getUpdator());

				// TODO ===消息推送给新服务站相关人员
				messagePushUtils.pushMessageByServiceStationId(workOrder.getId(), serviceStationId, String
						.format("您有新工单信息，工单号%s（FW号%s），请尽快处理", workOrder.getOrderNo(), workOrder.getCCSSOrderNo()));
			} else {
				// TODO ===消息推送给用户
				messagePushUtils.pushMessageByUserIds(oldWo.getId(),
						String.format("您有工单被关闭，工单号%s，请查看。", oldWo.getOrderNo()), oldWo.getCustomerId());
				// TODO ===消息推送给旧服务站相关人员（注：如果工单是技师关闭则消息也会推送给技师）
				messagePushUtils.pushMessageByServiceStationId(oldWo.getId(), oldWo.getServiceStationId(),
						String.format("您有工单异常关闭审核通过，工单号%s，请查看。", oldWo.getOrderNo()), oldWo.getUpdator());
			}

			ParameterTool.writeSuccessResponse(RequestContextHolder.getResponse());
		}
	}


	public String syncWorkOrderStatus(Long orderId, UserT user, Integer auditResult, String rejectedReason) {

		WorkOrderT workOrderT = workOrderTDao.getWorkOrderByOrderId(orderId);
		Map<String, Object> parameters1 = new HashMap<>();
		parameters1.put("orderNo", workOrderT.getOrderNo());
		parameters1.put("CRMNo", workOrderT.getOrderNoCrm());
		parameters1.put("billStatus", workOrderT.getOrderStatus());
		parameters1.put("actionTime", workOrderT.getUpdateTime());
		parameters1.put("directorName", user.getContact());
		parameters1.put("directorPhone", user.getPhone());
		parameters1.put("positionLat", 0);
		parameters1.put("positionLon", 0);
		parameters1.put("CCSSComplainerOrderNo", workOrderT.getOrderNoCrm());
		parameters1.put("CCSSOrderNo", workOrderT.getCCSSOrderNo());
		parameters1.put("customerName", workOrderT.getCustomerName());
		parameters1.put("customerPhone", workOrderT.getCustomerPhone());
		parameters1.put("customerCompany", workOrderT.getCustomerCompanyName());
		parameters1.put("faultDesc", workOrderT.getCustomerComplaint());


		// TODO ==== 添加审核结果字段  0:驳回   1:通过
		parameters1.put("auditResult", auditResult);
		// TODO ==== 添加驳回原因字段
		parameters1.put("rejectedReason", rejectedReason == null ? "" : rejectedReason);

		Map<String, Object> sSRepair = serviceStationDao.getStationNoAndNameByStationIdAndCompanyId(
				workOrderT.getServiceStationId(), workOrderT.getOrderChannel());
		if (org.apache.commons.collections.MapUtils.isNotEmpty(sSRepair)) {
			parameters1.put("stationNo", sSRepair.get("BusinessNo"));
			parameters1.put("stationName", sSRepair.get("StationName"));
		} else {
			parameters1.put("stationNo", "");
			parameters1.put("stationName", "");
		}
		try {
			CRMResponeEntity crmResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
					companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
					platformServiceDao, redisClientUtils, parameters1,null);
			if (crmResponeEntity.getStatus() != 0) {
				log.error("同步工单状态至CRM失败!状态:" + crmResponeEntity.getStatus() + ",错误信息:" + crmResponeEntity.getMessage());
			} else {
				net.sf.json.JSONObject data = crmResponeEntity.getData();
				if (data != null) {
					Object fwNo = data.get("CCSSOrderNo");
					return fwNo != null ? fwNo.toString() : null;
				}
			}
		} catch (Exception e) {
			log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
		}
		return null;
	}

	@Override
	@Transactional
	public void refuseCloseWorkOrderById(RefuseCloseWorkOrderCondition condition) {
		WorkOrderT wo = workOrderTDao.getWorkOrderByOrderId(condition.getOrderId());
		if (!Objects.isNull(wo)) {
			// 只有服务工单状态为待400主管审核时才可以进入操作
			if (wo.getOrderStatus() == 31) {
				// 根据服务工单操作流水查询出工单异常关闭之前的状态
				List<WorkOrderFlow> flows = workOrderFlowTDao.getWorkOrderBeforeCloseByOrderId(condition.getOrderId());
				if (CollectionUtils.isNotEmpty(flows)) {
					Integer orderStatus = flows.get(0).getProcessStatus();
					// 理论上流水保存的最新服务工单状态orderStatus与此时服务工单的状态相同
					if (orderStatus != null && orderStatus.equals(wo.getOrderStatus())) {
						WorkOrderFlow wof = null;
						// 从流水中拿到异常关闭之前的状态
						for (WorkOrderFlow wf : flows) {
							Integer processStatus = wf.getProcessStatus();
							if (processStatus != null && !processStatus.equals(wo.getOrderStatus())) {
								wof = wf;
								break;
							}
						}
						if (!Objects.isNull(wof)) {
							UserT user = UserThreadLocal.get();
							String currentTime = LocalTimeUtil.getRealCurrentTime();
							WorkOrderT temWo = new WorkOrderT();
							temWo.setId(wo.getId());
							temWo.setOrderStatus(wof.getProcessStatus());
							temWo.setUpdateTime(currentTime);
							temWo.setUpdator(user.getId());
							int count = workOrderTDao.updateWorkOrderById(temWo);
							if (count > 0) {

								// 如果服务工单回退的状态为诊断中则重置诊断结果
								if (temWo.getOrderStatus() == 26) {
									// 修改诊断结果字段IsBeginRepair为-1
									cCECDiagnoseRepairMsgTDao.updateIsBeginRepairByOrderId(wo.getId(), user.getId(),
											currentTime);
								}

								// 生成流水
								doSaveOperation(wo.getId(), wof.getProcessorId(), temWo.getOrderStatus(),
										"异常关闭400审核驳回,服务工单状态回退", condition.getLocLon(), condition.getLocLat(),
										condition.getLocation(), condition.getImei(), 0, user.getId(), currentTime,
										condition.getRefuseReason());

								// TODO ====同步工单状态到CRM
								syncWorkOrderStatus(wo.getId(), user, 0, condition.getRefuseReason());
								// 消息推送
								String content = String.format(
										"您的%s号工单（FW号%s），异常关闭申请不通过，不通过原因：%s，请继续服务或者拨打重康服务热线400-889-9990",
										wo.getOrderNo(), wo.getCCSSOrderNo(), condition.getRefuseReason());

								messagePushUtils.pushMessageByServiceStationIdAndOrderId(wo.getId(),
										wo.getServiceStationId(), wof.getProcessStatus().intValue(), content);

								ParameterTool.writeSuccessResponse(RequestContextHolder.getResponse());
							}else {
								ParameterTool.writeErrorResponse(RequestContextHolder.getResponse(), -45);
								throw new RuntimeException("服务工单更新失败");
							}
						} else {
							ParameterTool.writeErrorResponse(RequestContextHolder.getResponse(), -42);
							throw new RuntimeException("服务工单流水不正确，无法匹配到服务工单回退状态");
						}
					} else {
						ParameterTool.writeErrorResponse(RequestContextHolder.getResponse(), -42);
						throw new RuntimeException("服务工单流水不正确，无法匹配到服务工单回退状态");
					}
				} else {
					ParameterTool.writeErrorResponse(RequestContextHolder.getResponse(), -42);
					throw new RuntimeException("服务工单流水不正确，无法匹配到服务工单回退状态");
				}
			} else {
				ParameterTool.writeErrorResponse(RequestContextHolder.getResponse(), -23);
				throw new RuntimeException("该工单状态已变更！");
			}
		} else {
			ParameterTool.writeErrorResponse(RequestContextHolder.getResponse(), -41);
			throw new RuntimeException("服务工单不存在");
		}
	}

	@Override
	@Transactional
	public ModelAndView workOrderClosedAbnormally(WorkOrderCloseEntity workOrderCloseEntity) {

		int i = workOrderTDao.updateStatusByOrderNo(workOrderCloseEntity.getWorkOrderList(),
				workOrderCloseEntity.getStatus());
		if (i > 0) {
			ParameterTool.writeSuccessResponse(RequestContextHolder.getResponse());
			return null;
		}else{
			ParameterTool.writeErrorResponse(RequestContextHolder.getResponse(),-45);
			return null;
		}
	}

    @Override
    public ModelAndView updateWorkOrder(Map<String, Object> workOrderTMap, HttpServletResponse response) {
        Long id = MapUtils.getLong(workOrderTMap, "ID");
        if (null == id) {
            ParameterTool.writeErrorResponse(response, SMSEnum.type99.getIndex(), "请输入id");
			return null;
        }
        int i = workOrderTDao.updateByPrimaryKeySelective(workOrderTMap);
        if (i > 0) {
            ParameterTool.writeResponse(response, SMSEnum.type00.getIndex(), SMSEnum.type00.getName());
			return null;
        } else {
            ParameterTool.writeErrorResponse(response, SMSEnum.type99.getIndex(), "更新失败");
			return null;
		}
    }




	//sprint51需求   是否满足cds强关联    dbu服务工单强关联cds  jira：CDAP-4701
	@Override
	public ModelAndView isMeetStrongRelationCDS(Map<String, Object> map) {
		//sprint53 CDAP-5027 【CDS-WO】DBU工单-强制进入智能诊断-无需创建智能诊断工单
		//返回前端三个字段  前端根据这三个字段返回值  跳转对应页面
		//1.是否强关联非道路国四，排放等级  isMeetStrongRelationCDS    2.服务站是否有cds权限      3.当前esn的smn是否在cds支持清单内
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		long orderId = MapUtils.getLongValue(map,"orderId",-1);
		//1.是否强关联非道路国四，排放等级  isMeetStrongRelationCDS
		boolean isMeetStrongRelationCDS = false;
		Map<String, Object> returnMap = new HashMap<>();
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			if (orderId == -1) { //缺少必要参数
				obj.put("status", SMSEnum.type17.getIndex());
				obj.put("msg", SMSEnum.type17.getName());
				obj.put("data", "");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			Map<String,Object> orderMap = workOrderTDao.getOrderById(orderId);
			String smn = "";
			//3.当前esn的smn是否在cds支持清单内
			int isSupportCDS = 0;   //0：否   1：是
			if(MapUtils.isNotEmpty(orderMap)){
				String esn = MapUtils.getString(orderMap,"ESN","");
				String serviceSubtype = MapUtils.getString(orderMap,"ServiceSubtype","");
				String emissionLevel = MapUtils.getString(orderMap,"EmissionLevel","");
				returnMap.put("ESN", esn);
				returnMap.put("name", MapUtils.getString(orderMap,"CustomerName",""));
				returnMap.put("phone", MapUtils.getString(orderMap,"CustomerPhone",""));
				returnMap.put("workOrderId", orderId);
				returnMap.put("customerComplaint", MapUtils.getString(orderMap,"CustomerComplaint",""));
				//3.当前esn的smn是否在cds支持清单内
				Header userid = new BasicHeader("userid", request.getHeader("userid"));
				Header token = new BasicHeader("Authorization", request.getHeader("Authorization"));
				String url = PropertiesUtil.getProperties("projectconfig.properties", "getSMNByESNUrl");
				url = String.format(url, 0, esn);
				Map<String,Object> dataMap = null;
				String responseData = HttpUtils.get(url, new ResponseHandler<String>() {
					@Override
					public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
						if (response.getStatusLine().getStatusCode() == 200) {
							HttpEntity httpEntity = response.getEntity();
							return EntityUtils.toString(httpEntity);
						} else {
							log.error("异常，response：" + response);
						}
						return null;
					}
				}, userid, token);
				Map<String, Object> enginerMsg = JsonUtils.toJavaObject(responseData, Map.class);
				//status不为0代表该ESN没有获取到SMN或者SMN不在支持清单中
				if (MapUtils.getIntValue(enginerMsg, "status") == 0) {
					isSupportCDS = 1;
				}
				if(MapUtils.isNotEmpty(enginerMsg) && enginerMsg.containsKey("data")){
					dataMap = (Map<String,Object>)enginerMsg.get("data");
				}

                //1.是否强关联非道路国四，排放等级  isMeetStrongRelationCDS
				if(StringUtils.isNotEmpty(serviceSubtype) && "故障处理".equals(serviceSubtype.trim())){
					if(StringUtils.isEmpty(emissionLevel) || StringUtils.isEmpty(smn)){
						//调用CIP同步的表获取排放标准数据
						EngineMasterData engineMasterData = engineMasterDataMapper.selectByesn(esn);
						log.info("调用CIP同步的表获取排放标准数据，engineMasterData："+engineMasterData);
						if(null != engineMasterData && StringUtils.isEmpty(engineMasterData.getRelBulletinTelAboEmissionLevel())){
							emissionLevel = engineMasterData.getRelBulletinTelAboEmissionLevel();
						}
						if(null != engineMasterData && StringUtils.isEmpty(engineMasterData.getServiceModelName())){
							smn = engineMasterData.getServiceModelName();
						}
						if(StringUtils.isEmpty(emissionLevel) || StringUtils.isEmpty(smn)){
							//调用cip接口获取esn信息
							EsnBasicInfoEntity esnInfo = null;
							log.info("isMeetStrongRelationCDS强关联接口调用cip接口获取esn信息，orderId："+orderId);
							CipResponeEntity respone = CipApiUtils.getCipServiceApi().getEsnInfo(esn);
							if(null != respone && respone.getCode().equals(0)){
								esnInfo = (EsnBasicInfoEntity) net.sf.json.JSONObject.toBean(respone.getData(), EsnBasicInfoEntity.class);
								//设置排放信息
								if(null != esnInfo){
									emissionLevel = esnInfo.getEmissionLevel();
									smn = esnInfo.getServiceModelName();
								}
							}
						}
						if(StringUtils.isEmpty(smn) && MapUtils.isNotEmpty(dataMap)){
							smn = MapUtils.getString(dataMap,"SMN","");
						}
						//更新到工单表
						if(StringUtils.isNotEmpty(emissionLevel)){
							orderMap.put("EmissionLevel",emissionLevel);
							workOrderTDao.updateEmissionLevel(orderMap);
						}
					}
					returnMap.put("serviceSubtype",serviceSubtype);
					returnMap.put("emissionLevel",emissionLevel);
					if(StringUtils.isNotEmpty(serviceSubtype) && StringUtils.isNotEmpty(emissionLevel)){
						//查看是否满足强关联CDS智能诊断工单
						int num = dbuStrongRelationCDSConfigTDao.getDBUStrongRelationCDSConfigByMap(returnMap);
						if(num > 0){
							String smns = dbuStrongRelationCDSConfigTDao.getsmnsByMap(returnMap);
							if(StringUtils.isNotBlank(smns)){
								List<String> smnList = new ArrayList<>(Arrays.asList(smns.split(",")));
                                if(StringUtils.isNotBlank(smn) && smnList.contains(smn)){
									isMeetStrongRelationCDS = true;
								}
							} else {
								isMeetStrongRelationCDS = true;
							}
						}
					}
				}
			}

			//2.保存服务站是否有诊断维修的权限   默认值为0   没有权限
			int drFunStatus = 0;
			//移动技师可能不属于服务站    这块判断技师所属服务站是否有权限改为服务工单所属服务站是否有权限
			Map<String, Object> serviceStation = serviceStationDao.getServiceStationById(MapUtils.getLongValue(orderMap,"ServiceStationId"));
			if (MapUtils.isNotEmpty(serviceStation)) {
				drFunStatus = MapUtils.getIntValue(serviceStation,"DRFunStatus",0);
			}
			returnMap.put("SMN", smn);
			returnMap.put("isMeetStrongRelationCDS", isMeetStrongRelationCDS);
			returnMap.put("drFunStatus", drFunStatus);
			returnMap.put("isSupportCDS", isSupportCDS);
			obj.put("data", returnMap);
			obj.put("status", 0);
			obj.put("msg", "success");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			log.error(e.getMessage(), e);
		}
		return null;
	}


	//废弃了
	private boolean checkStationPowerPublic(Map<String,Object> map){
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		net.sf.json.JSONObject obj = new net.sf.json.JSONObject(); //声明返给前端json对象
		String userADId = AESTool.decryptString(request.getHeader("userid"));//解密userid
		UserT userT = loginDao.getUserByid(userADId);
		long orderId = MapUtils.getLongValue(map,"orderId",-1); //接收工单id
		// 判断是否有诊断工单在创建，或已完成智能诊断工单创建
		/*String key = "addOrder" + userT.getUserName();
		String value = redisClientUtils.get(key);
		if (StringUtils.isNotEmpty(value)){
			obj.put("status", -3);
			obj.put("msg", "该服务工单正在创建智能诊断中，请稍后再试！");
			ParameterTool.writeResponse(response, obj.toString());
		}
		int count = workOrderDrDao.getDRWorkOrderByOrderId(orderId);
		if (count > 0){
			obj.put("status", -3);
			obj.put("msg", "该服务工单已完成智能诊断工单的创建！");
			ParameterTool.writeResponse(response, obj.toString());
		}*/
		Map<String, Object> workOrderMap = new HashMap<>();
		workOrderMap.put("ID", orderId);
		WorkOrderT workOrderT = workOrderTDao.getWorkOrderTById(workOrderMap);
		//移动技师可能不属于服务站    这块判断技师所属服务站是否有权限改为服务工单所属服务站是否有权限
		Map<String, Object> serviceStation = serviceStationDao.getServiceStationById(workOrderT.getServiceStationId());
		int drFunStatus = 0; //保存服务站是否有诊断维修的权限   默认值为0   没有权限
		if (null != serviceStation) {
			drFunStatus = Integer.parseInt(serviceStation.get("DRFunStatus").toString());
		}
		if (drFunStatus == 0) { //没有诊断维修的权限
			/*obj.put("status", 0);
			obj.put("msg", "");
			Map<String, Object> data = new HashMap<>();
			data.put("DRFunStatus", drFunStatus);
			obj.put("data", data);
			//返回客户
			ParameterTool.writeResponse(response, obj.toString());*/
			return false;
		} else { //有诊断维修的权限
			String esn = workOrderT.getESN();
			Header userid = new BasicHeader("userid", request.getHeader("userid"));
			Header token = new BasicHeader("Authorization", request.getHeader("Authorization"));
			String url = PropertiesUtil.getProperties("projectconfig.properties", "getSMNByESNUrl");
			url = String.format(url, 0, esn);
			String responseData = HttpUtils.get(url, new ResponseHandler<String>() {
				@Override
				public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
					if (response.getStatusLine().getStatusCode() == 200) {
						HttpEntity httpEntity = response.getEntity();
						return EntityUtils.toString(httpEntity);
					} else {
						log.error("异常，response：" + response);
					}
					return null;
				}
			}, userid, token);
			Map<String, Object> enginerMsg = JsonUtils.toJavaObject(responseData, Map.class);
			//status不为0代表该ESN没有获取到SMN或者SMN不在支持清单中
			if (MapUtils.getIntValue(enginerMsg, "status") == 0) {
				//status为0代表ESN在支持清单中  需要把诊断维修生成工单的相关数据返给前端
				/*Map<String, Object> data = (Map<String, Object>) enginerMsg.get("data");
				data.put("name", workOrderT.getCustomerName());
				data.put("phone", workOrderT.getCustomerPhone());
				data.put("DRFunStatus", drFunStatus);
				data.put("workOrderId", workOrderT.getId());
				data.put("customerComplaint", workOrderT.getCustomerComplaint());*/
				return true;
			}
			return false;
			/*JSONObject json = new JSONObject(enginerMsg);
			ParameterTool.writeResponse(response, json.toString());*/
		}
	}



	@Override
	public ModelAndView srtSyncRepairAckToCRM(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		Map<String, Object> returnMap = new HashMap<>();
		UserT userT = UserThreadLocal.get();
		try {
			JSONObject obj = new JSONObject(); //声明返给前端json对象
			SaveRepairAckRequest saveRepairAckRequest = JSON.parseObject(MapUtils.getString(map, "contentJson"), SaveRepairAckRequest.class);
			//同步给crm前做字段转换
			Map<String,Object> contentJsonMap = convertSyncRepairAckToCRMParameter("CCI",saveRepairAckRequest);
			try {
				CRMResponeEntity CRMres = CRMApiUtils.getCRMServiceApi().syncRepairAckToCRM("CCI",platformServiceDao,redisClientUtils,contentJsonMap);
				if(CRMres.getStatus()!=0) {
					String errorMsg = "同步确认维修信息至CRM失败，状态："+CRMres.getStatus()+"，用户信息:"+CRMres.getMessage();
					insertExceptionDataSyncCrmT(saveRepairAckRequest, contentJsonMap,userT.getId(),errorMsg);
					//APP同步工单信息到CRM系统失败
					log.error(errorMsg);
				}
			} catch (Exception e) {
				insertExceptionDataSyncCrmT(saveRepairAckRequest, contentJsonMap,userT.getId(),"同步确认维修信息至CRM失败："+e.getMessage());
				//APP同步工单信息到CRM系统失败
				log.error("同步确认维修信息至CRM失败："+e.getMessage(),e);
			}

			obj.put("data", returnMap);
			obj.put("status", 0);
			obj.put("msg", "success");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			log.error(e.getMessage(), e);
		}
		return null;
	}




	public Map<String,Object> convertSyncRepairAckToCRMParameter(String channelName,SaveRepairAckRequest saveRepairAckRequest){
		Map<String,Object> convertParameter = new HashMap<>();
		if(channelName.equals(CRMServiceConst.DBU) || channelName.equals(CRMServiceConst.DBU_TEST)){
			Long wfOrderId = saveRepairAckRequest.getWfOrderId();
			Map<String,Object> orderMap = workOrderTDao.getOrderById(wfOrderId);
			if(MapUtils.isNotEmpty(orderMap)){
				convertParameter.put("orderNo",MapUtils.getString(orderMap,"OrderNo",""));
			}
			convertParameter.put("smn",saveRepairAckRequest.getSmn());
			convertParameter.put("drOrderNo",saveRepairAckRequest.getDrOrderNo());
			convertParameter.put("totalTime",saveRepairAckRequest.getTotalTime());
			List<SaveRepairAckRequest.FaultInfoListRequest> faultInfoList = saveRepairAckRequest.getFaultInfoList();
			List<Map<String,Object>> sendCrmFaultCodeList = new ArrayList<>();
			List<Map<String,Object>> sendCrmSymptomList = new ArrayList<>();
			if(CollectionUtils.isNotEmpty(faultInfoList)){
				for(SaveRepairAckRequest.FaultInfoListRequest faultInfoListRequest : faultInfoList){
					Map<String,Object> sendCrmFaultCodeMap = new HashMap<>();
					String faultInfoName = faultInfoListRequest.getFaultInfoName();
					//故障码症状类型，0-故障码，1-症状
					Integer faultInfoType = faultInfoListRequest.getFaultInfoType();
					List<Map<String,Object>> sendCrmSolutionList = new ArrayList<>();
					List<SaveRepairAckRequest.FaultInfoListRequest.SolutionListRequest> solutionList = faultInfoListRequest.getSolutionList();
					if(CollectionUtils.isNotEmpty(solutionList)){
						for(SaveRepairAckRequest.FaultInfoListRequest.SolutionListRequest solutionListRequest : solutionList){
							Map<String,Object> sendCrmSolutionMap = new HashMap<>();
							String solutionTitle = solutionListRequest.getSolutionTitle();
							Integer fulfilStatus = solutionListRequest.getFulfilStatus();
							String inspectionProcess = solutionListRequest.getInspectionProcess();
							String solutionCode = solutionListRequest.getSolutionCode();
							//是否选中维修确认，0-否，1-是
							Integer isCheckRepairAck = solutionListRequest.getIsCheckRepairAck();
							if(isCheckRepairAck == 1){   //只给crm选中的数据
								sendCrmSolutionMap.put("solutionID",solutionCode);  //美国solutionCode是crm的solutionId
								sendCrmSolutionMap.put("solutionName",solutionTitle);
								sendCrmSolutionMap.put("solutionStatus",fulfilStatus);
								sendCrmSolutionMap.put("inspectionProcess",inspectionProcess);
								List<Map<String,Object>> sendCrmComponentList = new ArrayList<>();
								List<SaveRepairAckRequest.FaultInfoListRequest.SolutionListRequest.photoListRequest> photoList = solutionListRequest.getPhotoList();
								List<SaveRepairAckRequest.FaultInfoListRequest.SolutionListRequest.ComponentListRequest> componentList = solutionListRequest.getComponentList();
								if(CollectionUtils.isNotEmpty(componentList)){
									for(SaveRepairAckRequest.FaultInfoListRequest.SolutionListRequest.ComponentListRequest componentListRequest : componentList){
										Map<String,Object> sendCrmComponentMap = new HashMap<>();
										sendCrmComponentMap.put("componentID",componentListRequest.getComponentId());
										sendCrmComponentMap.put("componentNum",componentListRequest.getComponentCount());
										if(StringUtils.isNotEmpty(componentListRequest.getWfc()) && StringUtils.isNotEmpty(componentListRequest.getFailCode())){
											sendCrmComponentMap.put("wfc",componentListRequest.getWfc()+componentListRequest.getFailCode());
										}else{
											sendCrmComponentMap.put("wfc","");
										}
										sendCrmComponentMap.put("failCodeName",componentListRequest.getFailName());
										sendCrmComponentMap.put("srtList",componentListRequest.getSrtList());
										sendCrmComponentList.add(sendCrmComponentMap);
									}
								}
								sendCrmSolutionMap.put("componentList",sendCrmComponentList);
								List<Map<String,Object>> sendCrmPhotoList = new ArrayList<>();
								if(CollectionUtils.isNotEmpty(photoList)){
									for(SaveRepairAckRequest.FaultInfoListRequest.SolutionListRequest.photoListRequest photoListRequest:photoList){
										Map<String,Object> sendCrmPhotoMap = new HashMap<>();
										sendCrmPhotoMap.put("photoUrl",photoListRequest.getPhotoUrl());
										sendCrmPhotoMap.put("type",photoListRequest.getType());
										sendCrmPhotoMap.put("status",photoListRequest.getStatus());
										sendCrmPhotoList.add(sendCrmPhotoMap);
									}
								}
								sendCrmSolutionMap.put("photoList",sendCrmPhotoList);
								sendCrmSolutionList.add(sendCrmSolutionMap);
							}
						}
					}
					sendCrmFaultCodeMap.put("solutionList",sendCrmSolutionList);
					if(faultInfoType == 0){
						sendCrmFaultCodeMap.put("faultCode",faultInfoName);
						sendCrmFaultCodeList.add(sendCrmFaultCodeMap);
					}
					if(faultInfoType == 1){
						sendCrmFaultCodeMap.put("symptom",faultInfoName);
						sendCrmSymptomList.add(sendCrmFaultCodeMap);
					}
				}
			}
			convertParameter.put("faultCodeList",sendCrmFaultCodeList);
			convertParameter.put("symptomList",sendCrmSymptomList);
		}
		return convertParameter;
	}


	public void insertExceptionDataSyncCrmT(SaveRepairAckRequest saveRepairAckRequest,Map<String,Object> contentJsonMap,Long operatorId,String failReason){
		Map<String,Object> exceptionDataSyncCrmTMap = new HashMap<>();
		exceptionDataSyncCrmTMap.put("OrderId",saveRepairAckRequest.getWfOrderId());
		exceptionDataSyncCrmTMap.put("DROrderId",saveRepairAckRequest.getDrOrderId());
		exceptionDataSyncCrmTMap.put("ExceptionData",JSON.toJSONString(contentJsonMap));
		exceptionDataSyncCrmTMap.put("IsSyncSuccess",0);
		exceptionDataSyncCrmTMap.put("FailReason",failReason);
		exceptionDataSyncCrmTMap.put("SyncNum",1);
		exceptionDataSyncCrmTMap.put("Flag",0);
		exceptionDataSyncCrmTMap.put("Creator",operatorId);
		exceptionDataSyncCrmTMap.put("CreateTime",LocalTimeUtil.getRealCurrentTime());
		exceptionDataSyncCrmTDao.insert(exceptionDataSyncCrmTMap);
	}

	@Override
	public ModelAndView updateWorkOrderByOcr(Map<String, Object> map, HttpServletResponse response) {
		Long id = MapUtils.getLong(map, "ID");
		if (null ==id) {
			ParameterTool.writeResponse(response, SMSEnum.type99.getIndex(), "请输入id");
			return null;
		}
		Map<String, Object> workOrderTMap = new HashMap<>();
		workOrderTMap.put("ID",id);
		workOrderTMap.put("OEMName",MapUtils.getString(map,"OEMName"));
		workOrderTMap.put("VIN",MapUtils.getString(map,"VIN"));
		workOrderTMap.put("ChassisNumber",MapUtils.getString(map,"ChassisNumber"));
		workOrderTMap.put("WarrantyStartDate",MapUtils.getString(map,"WarrantyStartDate"));
		int i = workOrderTDao.updateByPrimaryKeySelective(workOrderTMap);
		WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(id);
		//同步 ocr识别的数据到sf
		if (StringUtils.isNotBlank(MapUtils.getString(map,"OEMName"))||
		StringUtils.isNotBlank(MapUtils.getString(map,"VIN"))||
		StringUtils.isNotBlank(MapUtils.getString(map,"ChassisNumber"))||
		StringUtils.isNotBlank(MapUtils.getString(map,"WarrantyStartDate"))) {
			net.sf.json.JSONObject jsonObject = new net.sf.json.JSONObject();
			jsonObject.put("caseNumber",workOrderT.getOrderNoCrm());//sf case号
			jsonObject.put("warrantyStartDate",MapUtils.getString(map,"WarrantyStartDate"));//起保日期
			jsonObject.put("OEM",MapUtils.getString(map,"OEMName"));//OEM
			jsonObject.put("equipmentModel",MapUtils.getString(map,"VIN"));//设备型号
			jsonObject.put("VIN",MapUtils.getString(map,"ChassisNumber"));//VIN
			//同步sf
			this.sycOrcToSf(jsonObject.toString());
		}
		UserT userT = UserThreadLocal.get();
		OcrOrderVehicleLicenseRecord ocrOrderVehicleLicenseRecord = new OcrOrderVehicleLicenseRecord();
		ocrOrderVehicleLicenseRecord.setOrderId(workOrderT.getId());
		ocrOrderVehicleLicenseRecord.setOrderNo(workOrderT.getOrderNo());
		ocrOrderVehicleLicenseRecord.setChannel(workOrderT.getOrderChannel());
		ocrOrderVehicleLicenseRecord.setOrderNoCrm(workOrderT.getOrderNoCrm());
		ocrOrderVehicleLicenseRecord.setESN(workOrderT.getESN());
		ocrOrderVehicleLicenseRecord.setWarrantyStartDate(workOrderT.getWarrantyStartDate());
		ocrOrderVehicleLicenseRecord.setPhone(userT.getPhone());
		ocrOrderVehicleLicenseRecord.setVIN(workOrderT.getVIN());
		ocrOrderVehicleLicenseRecord.setChassisNumber(workOrderT.getChassisNumber());
		ocrOrderVehicleLicenseRecord.setOEMName(workOrderT.getoEMName());
		ocrOrderVehicleLicenseRecord.setFlag(0);
		ocrOrderVehicleLicenseRecord.setCreator(userT.getId());
		ocrOrderVehicleLicenseRecord.setCreateTime(LocalTimeUtil.getRealCurrentTime());
		ocrOrderVehicleLicenseRecordTMapper.insertSelective(ocrOrderVehicleLicenseRecord);
		if (i > 0) {
			ParameterTool.writeResponse(response, SMSEnum.type00.getIndex(), SMSEnum.type00.getName());
			return null;
		} else {
			ParameterTool.writeErrorResponse(response, SMSEnum.type99.getIndex(), "更新失败");
			return null;
		}
	}

	@Override
	public BaseResponse getWorkOrderByStationAndEsn(Long stationId, List<String> esnList) {
		//test
		List<WorkOrderT> list =workOrderTDao.getWorkOrderByStationAndEsn(stationId,esnList);
		if (CollectionUtils.isNotEmpty(list)) {
			return BaseResponse.success(list.stream().map(WorkOrderT::getESN).distinct().collect(Collectors.toList()));
		}else {
			return BaseResponse.success(new ArrayList<String>());
		}
	}

	public void sycOrcToSf(String jsonString){
		try {
			String methon = PropertiesUtil.getProperties("projectconfig.properties", "crm.cbu.username").trim();
			Map<String, Object> tokenAndHostMap = crmServiceApi.getCCICrmTokenAndHost();
			String url = MapUtils.getString(tokenAndHostMap, "hostUrl", "") + "OCRToSF";
			log.error("【DBU工单】【BE】智能识别内容对接DBU-SF----OCR url:" + url +"参数："+jsonString );
			String tokenStr = MapUtils.getString(tokenAndHostMap, "token", "");
			Header auth = new BasicHeader("Authorization", tokenStr);
			String response = HttpUtils.postJson(url, jsonString, new ResponseHandler<String>() {
				@Override
				public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
					if (response.getStatusLine().getStatusCode() == 200
							|| response.getStatusLine().getStatusCode() == 206) {
						HttpEntity httpEntity = response.getEntity();
						return EntityUtils.toString(httpEntity);
					} else {
						log.error("【DBU工单】【BE】智能识别内容对接DBU-SF----OCR" + jsonString + "；返回结果：" + response);
					}
					return null;
				}
			},auth);
		} catch (Exception e) {
			log.error("【DBU工单】【BE】智能识别内容对接DBU-SF----OCR" + jsonString);
			e.printStackTrace();
		}
	}

}
